Exemple #1
0
/*
 * util_file_pread -- reads from a file with an offset
 */
ssize_t
util_file_pread(const char *path, void *buffer, size_t size,
	off_t offset)
{
	if (!util_file_is_device_dax(path)) {
		int fd = util_file_open(path, NULL, 0, O_RDONLY);
		if (fd < 0)
			return -1;

		ssize_t read_len = pread(fd, buffer, size, offset);
		int olderrno = errno;
		(void) close(fd);
		errno = olderrno;
		return read_len;
	}

	ssize_t file_size = util_file_get_size(path);
	if (file_size < 0)
		return -1;

	size_t max_size = (size_t)(file_size - offset);
	if (size > max_size) {
		LOG(1, "Requested size of read goes beyond the mapped memory");
		size = max_size;
	}

	void *addr = util_file_map_whole(path);
	if (addr == NULL)
		return -1;

	memcpy(buffer, ADDR_SUM(addr, offset), size);
	util_unmap(addr, (size_t)file_size);
	return (ssize_t)size;
}
Exemple #2
0
/*
 * copy_data_to_broken_parts -- (internal) copy data to all parts created
 *                              in place of the broken ones
 */
static int
copy_data_to_broken_parts(struct pool_set *set, unsigned healthy_replica,
		unsigned flags, struct poolset_health_status *set_hs)
{
	size_t poolsize = replica_get_pool_size(set, healthy_replica);
	for (unsigned r = 0; r < set_hs->nreplicas; ++r) {
		/* skip unbroken and consistent replicas */
		if (replica_is_replica_healthy(r, set_hs))
			continue;

		struct pool_replica *rep = REP(set, r);
		struct pool_replica *rep_h = REP(set, healthy_replica);

		for (unsigned p = 0; p < rep->nparts; ++p) {
			/* skip unbroken parts from consistent replicas */
			if (!replica_is_part_broken(r, p, set_hs) &&
				replica_is_replica_consistent(r, set_hs))
				continue;

			const struct pool_set_part *part = &rep->part[p];

			size_t off = replica_get_part_data_offset(set, r, p);
			size_t len = replica_get_part_data_len(set, r, p);

			/* do not allow copying too much data */
			if (off >= poolsize)
				continue;

			if (off + len > poolsize)
				len = poolsize - off;

			void *src_addr = ADDR_SUM(rep_h->part[0].addr, off);

			/* First part of replica is mapped with header */
			size_t fpoff = (p == 0) ? POOL_HDR_SIZE : 0;

			/* copy all data */
			if (!is_dry_run(flags)) {
				memcpy(ADDR_SUM(part->addr, fpoff),
						src_addr, len);
				pmem_msync(ADDR_SUM(part->addr, fpoff), len);
			}
		}
	}
	return 0;
}
Exemple #3
0
/*
 * copy_replica_data_bw -- (internal) copy data between replicas of two
 *                         poolsets, starting from the end of the pool
 */
static void
copy_replica_data_bw(struct pool_set *set_dst, struct pool_set *set_src,
		unsigned repn)
{
	LOG(3, "set_in %p, set_out %p, repn %u", set_src, set_dst, repn);
	ssize_t pool_size = replica_get_pool_size(set_src, repn);
	if (pool_size < 0) {
		LOG(1, "getting pool size from replica %u failed", repn);
		pool_size = (ssize_t)set_src->poolsize;
	}

	size_t len = (size_t)pool_size - POOL_HDR_SIZE -
			replica_get_part_data_len(set_src, repn, 0);
	size_t count = len / POOL_HDR_SIZE;
	void *src = ADDR_SUM(PART(REP(set_src, repn), 1)->addr, len);
	void *dst = ADDR_SUM(PART(REP(set_dst, repn), 1)->addr, len);
	while (count-- > 0) {
		src = ADDR_SUM(src, -(ssize_t)POOL_HDR_SIZE);
		dst = ADDR_SUM(dst, -(ssize_t)POOL_HDR_SIZE);
		pmem_memcpy_persist(dst, src, POOL_HDR_SIZE);
	}
}
Exemple #4
0
/*
 * util_file_pread -- reads from a file with an offset
 */
ssize_t
util_file_pread(const char *path, void *buffer, size_t size,
	os_off_t offset)
{
	LOG(3, "path \"%s\" buffer %p size %zu offset %ju",
			path, buffer, size, offset);

	enum file_type type = util_file_get_type(path);
	if (type < 0)
		return -1;

	if (type == TYPE_NORMAL) {
		int fd = util_file_open(path, NULL, 0, O_RDONLY);
		if (fd < 0) {
			LOG(2, "failed to open file \"%s\"", path);
			return -1;
		}

		ssize_t read_len = pread(fd, buffer, size, offset);
		int olderrno = errno;
		(void) os_close(fd);
		errno = olderrno;
		return read_len;
	}

	ssize_t file_size = util_file_get_size(path);
	if (file_size < 0) {
		LOG(2, "cannot determine file length \"%s\"", path);
		return -1;
	}

	size_t max_size = (size_t)(file_size - offset);
	if (size > max_size) {
		LOG(2, "requested size of read goes beyond the file length, "
			"%zu > %zu", size, max_size);
		LOG(4, "adjusting size to %zu", max_size);
		size = max_size;
	}

	void *addr = util_file_map_whole(path);
	if (addr == NULL) {
		LOG(2, "failed to map entire file \"%s\"", path);
		return -1;
	}

	memcpy(buffer, ADDR_SUM(addr, offset), size);
	util_unmap(addr, (size_t)file_size);
	return (ssize_t)size;
}
Exemple #5
0
/*
 * copy_data_to_broken_parts -- (internal) copy data to all parts created
 *                              in place of the broken ones
 */
static int
copy_data_to_broken_parts(struct pool_set *set, unsigned healthy_replica,
		unsigned flags, struct poolset_health_status *set_hs)
{
	/* get pool size from healthy replica */
	size_t poolsize = set->poolsize;

	for (unsigned r = 0; r < set_hs->nreplicas; ++r) {
		/* skip unbroken and consistent replicas */
		if (replica_is_replica_healthy(r, set_hs))
			continue;

		struct pool_replica *rep = REP(set, r);
		struct pool_replica *rep_h = REP(set, healthy_replica);

		for (unsigned p = 0; p < rep->nparts; ++p) {
			/* skip unbroken parts from consistent replicas */
			if (!replica_is_part_broken(r, p, set_hs) &&
				replica_is_replica_consistent(r, set_hs))
				continue;

			const struct pool_set_part *part = &rep->part[p];

			size_t off = replica_get_part_data_offset(set, r, p);
			size_t len = replica_get_part_data_len(set, r, p);

			if (rep->remote)
				len = poolsize - off;

			/* do not allow copying too much data */
			if (off >= poolsize)
				continue;

			/*
			 * First part of replica is mapped
			 * with header
			 */
			size_t fpoff = (p == 0) ? POOL_HDR_SIZE : 0;
			void *dst_addr = ADDR_SUM(part->addr, fpoff);

			if (rep->remote) {
				int ret = Rpmem_persist(rep->remote->rpp,
						off - POOL_HDR_SIZE, len, 0);
				if (ret) {
					LOG(1, "Copying data to remote node "
						"failed -- '%s' on '%s'",
						rep->remote->pool_desc,
						rep->remote->node_addr);
					return -1;
				}
			} else if (rep_h->remote) {
				int ret = Rpmem_read(rep_h->remote->rpp,
						dst_addr,
						off - POOL_HDR_SIZE, len);
				if (ret) {
					LOG(1, "Reading data from remote node "
						"failed -- '%s' on '%s'",
						rep_h->remote->pool_desc,
						rep_h->remote->node_addr);
					return -1;
				}
			} else {
				if (off + len > poolsize)
					len = poolsize - off;

				void *src_addr =
					ADDR_SUM(rep_h->part[0].addr, off);

				/* copy all data */
				memcpy(dst_addr, src_addr, len);
				pmem_msync(dst_addr, len);
			}
		}
	}
	return 0;
}