示例#1
0
/*
 * rpmemd_fip_getinfo -- obtain fabric interface information
 */
static int
rpmemd_fip_getinfo(struct rpmemd_fip *fip, const char *service,
	const char *node, enum rpmem_provider provider)
{
	int ret;

	struct fi_info *hints = rpmem_fip_get_hints(provider);
	if (!hints) {
		RPMEMD_LOG(ERR, "getting fabric interface hints");
		ret = -1;
		goto err_fi_get_hints;
	}

	ret = fi_getinfo(RPMEM_FIVERSION, node, service, 0,
			hints, &fip->fi);
	if (ret) {
		RPMEMD_FI_ERR(ret, "getting fabric interface information");
		goto err_fi_getinfo;
	}

	if (fip->fi->addr_format != FI_SOCKADDR_IN) {
		RPMEMD_LOG(ERR, "unsupported address family -- %d",
				fip->fi->addr_format);
		goto err_addr_format;
	}

	fi_freeinfo(hints);
	return 0;
err_addr_format:
	fi_freeinfo(fip->fi);
err_fi_getinfo:
	fi_freeinfo(hints);
err_fi_get_hints:
	return ret;
}
示例#2
0
/*
 * rpmemd_req_close -- handle close request
 */
static int
rpmemd_req_close(struct rpmemd_obc *obc, void *arg)
{
    RPMEMD_ASSERT(arg != NULL);
    RPMEMD_LOG(NOTICE, "close request");

    struct rpmemd *rpmemd = (struct rpmemd *)arg;

    rpmemd->closing = 1;

    int ret;
    int status = 0;

    if (!rpmemd->pool) {
        RPMEMD_LOG(ERR, "pool not opened");
        status = RPMEM_ERR_FATAL;
        return rpmemd_obc_close_resp(rpmemd->obc, status);
    }

    ret = rpmemd_fip_stop(rpmemd);
    if (ret) {
        status = RPMEM_ERR_FATAL;
    } else {
        rpmemd_fip_close(rpmemd->fip);
        rpmemd_fip_fini(rpmemd->fip);
    }

    int remove = rpmemd->created && status;
    ret = rpmemd_close_pool(rpmemd, remove);

    RPMEMD_LOG(NOTICE, "close request response (status = %u)", status);
    ret = rpmemd_obc_close_resp(rpmemd->obc, status);

    return ret;
}
示例#3
0
/*
 * rpmemd_req_set_attr -- handle set attributes request
 */
static int
rpmemd_req_set_attr(struct rpmemd_obc *obc, void *arg,
	const struct rpmem_pool_attr *pool_attr)
{
	RPMEMD_ASSERT(arg != NULL);
	RPMEMD_LOG(NOTICE, "set attributes request");
	struct rpmemd *rpmemd = (struct rpmemd *)arg;
	RPMEMD_ASSERT(rpmemd->pool != NULL);

	int ret;
	int status = 0;
	int err_send = 1;

	ret = rpmemd_db_pool_set_attr(rpmemd->pool, pool_attr);
	if (ret) {
		ret = -1;
		status = rpmemd_db_get_status(errno);
		goto err_set_attr;
	}

	RPMEMD_LOG(NOTICE, "new pool attributes:");
	rpmemd_print_pool_attr(pool_attr);

	ret = rpmemd_obc_set_attr_resp(obc, status);
	if (ret)
		goto err_set_attr_resp;

	return ret;
err_set_attr_resp:
	err_send = 0;
err_set_attr:
	if (err_send)
		ret = rpmemd_obc_set_attr_resp(obc, status);
	return ret;
}
示例#4
0
文件: rpmemd.c 项目: plebioda/nvml
/*
 * rpmemd_print_pool_attr -- print pool attributes
 */
static void
rpmemd_print_pool_attr(const struct rpmem_pool_attr *attr)
{
	if (attr == NULL) {
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "NULL");
	} else {
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "signature: '%s'",
				_str(attr->signature));
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "major: %u", attr->major);
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "compat_features: 0x%x",
				attr->compat_features);
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "incompat_features: 0x%x",
				attr->incompat_features);
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "ro_compat_features: 0x%x",
				attr->ro_compat_features);
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "poolset_uuid: %s",
				uuid2str(attr->poolset_uuid));
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "uuid: %s",
				uuid2str(attr->uuid));
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "next_uuid: %s",
				uuid2str(attr->next_uuid));
		RPMEMD_LOG(INFO, RPMEMD_LOG_INDENT "prev_uuid: %s",
			uuid2str(attr->prev_uuid));
	}
}
示例#5
0
/*
 * rpmemd_close_pool -- close pool and remove it if required
 */
static int
rpmemd_close_pool(struct rpmemd *rpmemd, int remove)
{
	int ret = 0;

	RPMEMD_LOG(NOTICE, "closing pool");
	rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
	RPMEMD_LOG(INFO, "pool closed");

	if (remove) {
		RPMEMD_LOG(NOTICE, "removing '%s'", rpmemd->pool_desc);
		ret = rpmemd_db_pool_remove(rpmemd->db,
				rpmemd->pool_desc, 0, 0);
		if (ret) {
			RPMEMD_LOG(ERR, "!removing pool '%s' failed",
					rpmemd->pool_desc);
		} else {
			RPMEMD_LOG(INFO, "removed '%s'", rpmemd->pool_desc);
		}
	}

	free(rpmemd->pool_desc);

	return ret;
}
示例#6
0
文件: rpmemd.c 项目: gaoning777/nvml
/*
 * rpmemd_req_close -- handle close request
 */
static int
rpmemd_req_close(struct rpmemd_obc *obc, void *arg)
{
	RPMEMD_ASSERT(arg != NULL);

	struct rpmemd *rpmemd = (struct rpmemd *)arg;

	rpmemd->closing = 1;

	int ret;
	int status = 0;

	if (!rpmemd->pool) {
		RPMEMD_LOG(ERR, "pool not opened");
		status = RPMEM_ERR_FATAL;
		return rpmemd_obc_close_resp(rpmemd->obc, status);
	}

	rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);

	ret = rpmemd_fip_process_stop(rpmemd->fip);
	if (ret) {
		RPMEMD_LOG(ERR, "!stopping fip process failed");
		status = errno;
	}

	ret = rpmemd_obc_close_resp(rpmemd->obc, status);
	if (!ret)
		rpmemd_fip_wait_close(rpmemd->fip, -1);

	rpmemd_fip_close(rpmemd->fip);
	rpmemd_fip_fini(rpmemd->fip);

	return ret;
}
示例#7
0
文件: rpmemd.c 项目: gaoning777/nvml
/*
 * rpmemd_get_ssh_addr -- returns an address which the ssh connection is
 * established on
 *
 * This function utilizes the SSH_CONNECTION environment variable to retrieve
 * the server IP address. See ssh(1) for details.
 */
static char *
rpmemd_get_ssh_addr(void)
{
	char *ssh_conn = getenv("SSH_CONNECTION");
	if (!ssh_conn) {
		RPMEMD_LOG(ERR, "SSH_CONNECTION variable is not set");
		return NULL;
	}

	char *sp = strchr(ssh_conn, ' ');
	if (!sp) {
		RPMEMD_LOG(ERR, "invalid format of SSH_CONNECTION variable");
		return NULL;
	}

	char *addr = strchr(sp + 1, ' ');
	if (!addr) {
		RPMEMD_LOG(ERR, "invalid format of SSH_CONNECTION variable");
		return NULL;
	}

	addr++;

	sp = strchr(addr, ' ');
	if (!sp) {
		RPMEMD_LOG(ERR, "invalid format of SSH_CONNECTION variable");
		return NULL;
	}

	*sp = '\0';

	return addr;
}
示例#8
0
/*
 * rpmem_print_pm_policy -- print persistency method policy
 */
static void
rpmem_print_pm_policy(enum rpmem_persist_method persist_method,
		int (*persist)(const void *addr, size_t len))
{
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist method: %s",
			rpmem_persist_method_to_str(persist_method));
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "persist flush: %s",
			rpmemd_persist_to_str(persist));
}
示例#9
0
/*
 * rpmemd_print_resp_attr -- print response attributes
 */
static void
rpmemd_print_resp_attr(const struct rpmem_resp_attr *attr)
{
    RPMEMD_LOG(NOTICE, "\tport: %u", attr->port);
    RPMEMD_LOG(NOTICE, "\trkey: 0x%lx", attr->rkey);
    RPMEMD_LOG(NOTICE, "\traddr: 0x%lx", attr->raddr);
    RPMEMD_LOG(NOTICE, "\tnlanes: %u", attr->nlanes);
    RPMEMD_LOG(NOTICE, "\tpersist method: %s",
               rpmem_persist_method_to_str(attr->persist_method));
}
示例#10
0
/*
 * test_log_messages -- test log messages on specified level
 */
static void
test_log_messages(enum rpmemd_log_level level)
{
	rpmemd_log_level = level;

	RPMEMD_LOG(ERR, "ERR message on %s level", l2s(level));
	RPMEMD_LOG(WARN, "WARN message on %s level", l2s(level));
	RPMEMD_LOG(NOTICE, "NOTICE message on %s level", l2s(level));
	RPMEMD_LOG(INFO, "INFO message on %s level", l2s(level));
	RPMEMD_DBG("DBG message on %s level", l2s(level));
}
示例#11
0
文件: rpmemd.c 项目: plebioda/nvml
/*
 * rpmemd_common_fip_init -- initialize fabric provider
 */
static int
rpmemd_common_fip_init(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
	struct rpmem_resp_attr *resp, int *status)
{
	/* register the whole pool with header in RDMA */
	void *addr = (void *)((uintptr_t)rpmemd->pool->pool_addr);
	struct rpmemd_fip_attr fip_attr = {
		.addr		= addr,
		.size		= req->pool_size,
		.nlanes		= req->nlanes,
		.nthreads	= rpmemd->nthreads,
		.provider	= req->provider,
		.persist_method = rpmemd->persist_method,
		.deep_persist	= rpmemd_deep_persist,
		.ctx		= rpmemd
	};

	const int is_pmem = rpmemd_db_pool_is_pmem(rpmemd->pool);
	if (rpmemd_apply_pm_policy(&fip_attr.persist_method, &fip_attr.persist,
			is_pmem)) {
		*status = RPMEM_ERR_FATAL;
		goto err_fip_init;
	}

	const char *node = rpmem_get_ssh_conn_addr();
	enum rpmem_err err;

	rpmemd->fip = rpmemd_fip_init(node, NULL, &fip_attr, resp, &err);
	if (!rpmemd->fip) {
		*status = (int)err;
		goto err_fip_init;
	}

	return 0;
err_fip_init:
	return -1;
}

/*
 * rpmemd_print_req_attr -- print request attributes
 */
static void
rpmemd_print_req_attr(const struct rpmem_req_attr *req)
{
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "pool descriptor: '%s'",
			_str(req->pool_desc));
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "pool size: %lu", req->pool_size);
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "nlanes: %u", req->nlanes);
	RPMEMD_LOG(NOTICE, RPMEMD_LOG_INDENT "provider: %s",
			rpmem_provider_to_str(req->provider));
}
示例#12
0
/*
 * rpmemd_fip_stop_thread -- stop background thread for in-band connection
 */
static int
rpmemd_fip_stop_thread(struct rpmemd *rpmemd)
{
    RPMEMD_ASSERT(rpmemd->fip_running);
    void *tret;
    errno = pthread_join(rpmemd->fip_thread, &tret);
    if (errno)
        RPMEMD_LOG(ERR, "!waiting for in-band thread");

    int ret = (int)(uintptr_t)tret;
    if (ret)
        RPMEMD_LOG(ERR, "in-band thread failed -- '%d'", ret);

    return ret;
}
示例#13
0
/*
 * print_help -- (internal) prints help message
 */
static void
print_help(const char *name)
{
	print_usage(name);
	print_version();
	RPMEMD_LOG(ERR, help_str, DAEMON_NAME);
}
示例#14
0
/*
 * rpmemd_fip_cq_thread -- completion queue worker thread
 */
static void *
rpmemd_fip_cq_thread(void *arg)
{
	struct rpmemd_fip *fip = arg;
	struct fi_cq_err_entry err;
	const char *str_err;
	ssize_t sret;
	int ret = 0;

	while (!fip->closing) {
		sret = fi_cq_sread(fip->cq, fip->cq_entries,
				fip->cq_size, NULL,
				RPMEM_FIP_CQ_WAIT_MS);
		if (unlikely(fip->closing))
			break;

		if (unlikely(sret == -FI_EAGAIN))
			continue;

		if (unlikely(sret < 0)) {
			ret = (int)sret;
			goto err_cq_read;
		}

		for (ssize_t i = 0; i < sret; i++) {
			struct fi_cq_msg_entry *entry = &fip->cq_entries[i];
			RPMEMD_ASSERT(entry->op_context);

			struct rpmemd_fip_lane *lanep = entry->op_context;

			/* signal lane about SEND completion */
			if (entry->flags & FI_SEND)
				rpmem_fip_lane_signal(&lanep->lane, FI_SEND);

			/* add lane to worker's ring buffer */
			if (entry->flags & FI_RECV) {
				ret = rpmemd_fip_worker_push(lanep->worker,
						lanep);
			}

			if (ret)
				goto err;
		}

	}

	return 0;
err_cq_read:
	sret = fi_cq_readerr(fip->cq, &err, 0);
	if (sret < 0) {
		RPMEMD_FI_ERR((int)sret, "error reading from completion queue: "
			"cannot read error from completion queue");
		goto err;
	}

	str_err = fi_cq_strerror(fip->cq, err.prov_errno, NULL, NULL, 0);
	RPMEMD_LOG(ERR, "error reading from completion queue: %s", str_err);
err:
	return (void *)(uintptr_t)ret;
}
示例#15
0
/*
 * rpmemd_fip_set_resp -- fill the response structure
 */
static int
rpmemd_fip_set_resp(struct rpmemd_fip *fip, struct rpmem_resp_attr *resp)
{
	int ret;
	struct sockaddr_in addr_in;
	size_t addrlen = sizeof(addr_in);

	ret = fi_getname(&fip->pep->fid, &addr_in, &addrlen);
	if (ret) {
		RPMEMD_FI_ERR(ret, "getting local endpoint address");
		goto err_fi_getname;
	}

	if (!addr_in.sin_port) {
		RPMEMD_LOG(ERR, "dynamic allocation of port failed");
		goto err_port;
	}

	resp->port = htons(addr_in.sin_port);
	resp->rkey = fi_mr_key(fip->mr);
	resp->persist_method = fip->persist_method;
	resp->raddr = (uint64_t)fip->addr;
	resp->nlanes = fip->nlanes;

	return 0;
err_port:
err_fi_getname:
	return -1;
}
示例#16
0
/*
 * rpmemd_print_pool_attr -- print pool attributes
 */
static void
rpmemd_print_pool_attr(const struct rpmem_pool_attr *attr)
{
    RPMEMD_LOG(INFO, "\tsignature: '%s'", _str(attr->signature));
    RPMEMD_LOG(INFO, "\tmajor: %u", attr->major);
    RPMEMD_LOG(INFO, "\tcompat_features: 0x%x", attr->compat_features);
    RPMEMD_LOG(INFO, "\tincompat_features: 0x%x", attr->incompat_features);
    RPMEMD_LOG(INFO, "\tro_compat_features: 0x%x",
               attr->ro_compat_features);
    RPMEMD_LOG(INFO, "\tpoolset_uuid: %s", uuid2str(attr->poolset_uuid));
    RPMEMD_LOG(INFO, "\tuuid: %s", uuid2str(attr->uuid));
    RPMEMD_LOG(INFO, "\tnext_uuid: %s", uuid2str(attr->next_uuid));
    RPMEMD_LOG(INFO, "\tprev_uuid: %s", uuid2str(attr->prev_uuid));
}
示例#17
0
/*
 * rpmemd_fip_process_stop_gpspm -- stop processing GPSPM messages
 */
static int
rpmemd_fip_process_stop_gpspm(struct rpmemd_fip *fip)
{
	int lret = 0;

	/* this stops all worker threads */
	fip->closing = 1;

	/*
	 * Signal all lanes that SEND has been completed.
	 * Some workers may still be waiting for this completion.
	 */
	for (unsigned i = 0; i < fip->nlanes; i++)
		rpmem_fip_lane_signal(&fip->lanes[i].lane, FI_SEND);

	void *tret;
	int ret;
	errno = pthread_join(fip->cq_thread, &tret);
	if (errno) {
		RPMEMD_LOG(ERR, "!joining cq thread");
		lret = -1;
	} else {
		ret = (int)(uintptr_t)tret;
		if (ret) {
			RPMEMD_LOG(ERR, "cq thread failed with "
				"code -- %d", ret);
			lret = ret;
		}
	}

	free(fip->cq_entries);

	for (size_t i = 0; i < fip->nthreads; i++) {
		ret = rpmemd_fip_worker_fini(fip->workers[i]);
		if (ret) {
			RPMEMD_LOG(ERR, "worker failed with code -- %d", ret);
			lret = ret;
		}
	}

	free(fip->workers);

	return lret;
}
示例#18
0
/*
 * rpmemd_check_pool -- verify pool parameters
 */
static int
rpmemd_check_pool(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
                  int *status)
{
    if (rpmemd->pool->pool_size < RPMEM_MIN_POOL) {
        RPMEMD_LOG(ERR, "invalid pool size -- must be >= %zu",
                   RPMEM_MIN_POOL);
        *status = RPMEM_ERR_FATAL;
        return -1;
    }

    if (rpmemd->pool->pool_size - POOL_HDR_SIZE < req->pool_size) {
        RPMEMD_LOG(ERR, "requested size is too big");
        *status = RPMEM_ERR_BADSIZE;
        return -1;
    }

    return 0;
}
示例#19
0
/*
 * rpmemd_common_fip_init -- initialize fabric provider
 */
static int
rpmemd_common_fip_init(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
                       struct rpmem_resp_attr *resp, int *status)
{
    void *addr = (void *)((uintptr_t)rpmemd->pool->pool_addr +
                          POOL_HDR_SIZE);
    struct rpmemd_fip_attr fip_attr = {
        .addr		= addr,
        .size		= req->pool_size,
        .nlanes		= req->nlanes,
        .nthreads	= rpmemd->nthreads,
        .provider	= req->provider,
        .persist_method = rpmemd->persist_method,
        .persist	= rpmemd->persist,
    };

    const char *node = rpmem_get_ssh_conn_addr();
    enum rpmem_err err;

    rpmemd->fip = rpmemd_fip_init(node, NULL, &fip_attr, resp, &err);
    if (!rpmemd->fip) {
        *status = (int)err;
        goto err_fip_init;
    }

    return 0;
err_fip_init:
    return -1;
}

/*
 * rpmemd_print_req_attr -- print request attributes
 */
static void
rpmemd_print_req_attr(const struct rpmem_req_attr *req)
{
    RPMEMD_LOG(NOTICE, "\tpool descriptor: '%s'", _str(req->pool_desc));
    RPMEMD_LOG(NOTICE, "\tpool size: %lu", req->pool_size);
    RPMEMD_LOG(NOTICE, "\tnlanes: %u", req->nlanes);
    RPMEMD_LOG(NOTICE, "\tprovider: %s",
               rpmem_provider_to_str(req->provider));
}
示例#20
0
/*
 * rpmemd_get_nthreads -- returns number of threads to use for fabric
 * processing
 */
static size_t
rpmemd_get_nthreads(void)
{
    long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
    if (ncpus < 0) {
        RPMEMD_LOG(ERR, "getting number of CPUs");
        return 0;
    }

    return (size_t)ncpus;
}
示例#21
0
/*
 * rpmemd_fip_check_pmsg -- verify persist message
 */
static inline int
rpmemd_fip_check_pmsg(struct rpmemd_fip *fip, struct rpmem_msg_persist *pmsg)
{
	if (pmsg->lane >= fip->nlanes) {
		RPMEMD_LOG(ERR, "invalid lane number -- %lu", pmsg->lane);
		return -1;
	}

	uintptr_t raddr = pmsg->addr;
	uintptr_t laddr = (uintptr_t)fip->addr;

	if (raddr < laddr || raddr + pmsg->size > laddr + fip->size) {
		RPMEMD_LOG(ERR, "invalid address or size requested "
			"for persist operation (0x%lx, %lu)",
			raddr, pmsg->size);
		return -1;
	}

	return 0;
}
示例#22
0
文件: rpmemd.c 项目: gaoning777/nvml
/*
 * rpmemd_check_pool -- verify pool parameteres
 */
static int
rpmemd_check_pool(struct rpmemd *rpmemd, const struct rpmem_req_attr *req,
	int *status)
{
	if (rpmemd->pool->pool_size - POOL_HDR_SIZE < req->pool_size) {
		RPMEMD_LOG(ERR, "requested size is too big");
		*status = RPMEM_ERR_BADSIZE;
		return -1;
	}

	return 0;
}
示例#23
0
/*
 * rpmemd_fip-stop -- stop in-band thread and stop processing thread
 */
static int
rpmemd_fip_stop(struct rpmemd *rpmemd)
{
    int ret;

    int fip_ret = rpmemd_fip_stop_thread(rpmemd);
    if (fip_ret) {
        RPMEMD_LOG(ERR, "!in-band thread failed");
    }

    if (!fip_ret) {
        ret = rpmemd_fip_process_stop(rpmemd->fip);
        if (ret) {
            RPMEMD_LOG(ERR, "!stopping fip process failed");
        }
    }

    rpmemd->fip_running = 0;

    return fip_ret;
}
示例#24
0
/*
 * rpmemd_fip_thread -- background thread for establishing in-band connection
 */
static void *
rpmemd_fip_thread(void *arg)
{
    struct rpmemd *rpmemd = (struct rpmemd *)arg;
    int ret;

    RPMEMD_LOG(INFO, "waiting for in-band connection");

    ret = rpmemd_fip_accept(rpmemd->fip, RPMEM_ACCEPT_TIMEOUT);
    if (ret)
        goto err_accept;

    RPMEMD_LOG(NOTICE, "in-band connection established");

    ret = rpmemd_fip_process_start(rpmemd->fip);
    if (ret)
        goto err_process_start;

    return NULL;
err_process_start:
    rpmemd_fip_close(rpmemd->fip);
err_accept:
    return (void *)(uintptr_t)ret;
}
示例#25
0
/*
 * rpmemd_fip_start_thread -- start background thread for establishing
 * in-band connection
 */
static int
rpmemd_fip_start_thread(struct rpmemd *rpmemd)
{
    errno = pthread_create(&rpmemd->fip_thread, NULL,
                           rpmemd_fip_thread, rpmemd);
    if (errno) {
        RPMEMD_LOG(ERR, "!creating in-band thread");
        goto err_pthread_create;
    }

    rpmemd->fip_running = 1;

    return 0;
err_pthread_create:
    return -1;
}
示例#26
0
/*
 * rpmemd_apply_pm_policy -- choose the persistency method and the flush
 * function according to the pool type and the persistency method read from the
 * config
 */
int
rpmemd_apply_pm_policy(enum rpmem_persist_method *persist_method,
	int (**persist)(const void *addr, size_t len),
	void *(**memcpy_persist)(void *pmemdest, const void *src, size_t len),
	const int is_pmem)
{
	switch (*persist_method) {
	case RPMEM_PM_APM:
		if (is_pmem) {
			*persist_method = RPMEM_PM_APM;
			*persist = rpmemd_flush_fatal;
		} else {
			*persist_method = RPMEM_PM_GPSPM;
			*persist = pmem_msync;
		}
		break;
	case RPMEM_PM_GPSPM:
		*persist_method = RPMEM_PM_GPSPM;
		*persist = is_pmem ? rpmemd_pmem_persist : pmem_msync;
		break;
	default:
		RPMEMD_FATAL("invalid persist method: %d", *persist_method);
		return -1;
	}

	/* this is for RPMEM_PERSIST_INLINE */
	if (is_pmem)
		*memcpy_persist = pmem_memcpy_persist;
	else
		*memcpy_persist = rpmem_memcpy_msync;

	RPMEMD_LOG(NOTICE, "persistency policy:");
	rpmem_print_pm_policy(*persist_method, *persist);

	return 0;
}
示例#27
0
/*
 * rpmemd_print_info -- print basic info and configuration
 */
static void
rpmemd_print_info(struct rpmemd *rpmemd)
{
    RPMEMD_LOG(NOTICE, "ssh connection: %s",
               _str(getenv("SSH_CONNECTION")));
    RPMEMD_LOG(NOTICE, "user: %s", _str(getenv("USER")));
    RPMEMD_LOG(NOTICE, "configuration");
    RPMEMD_LOG(NOTICE, "\tpool set directory: '%s'",
               _str(rpmemd->config.poolset_dir));
    RPMEMD_LOG(NOTICE, "\tpersist method: %s",
               rpmem_persist_method_to_str(rpmemd->persist_method));
    RPMEMD_LOG(NOTICE, "\tnumber of threads: %lu", rpmemd->nthreads);
    RPMEMD_DBG("\tpersist APM: %s",
               bool2str(rpmemd->config.persist_apm));
    RPMEMD_DBG("\tpersist GPSPM: %s",
               bool2str(rpmemd->config.persist_general));
    RPMEMD_DBG("\tuse syslog: %s", bool2str(rpmemd->config.use_syslog));
    RPMEMD_DBG("\tlog file: %s", _str(rpmemd->config.log_file));
    RPMEMD_DBG("\tlog level: %s",
               rpmemd_log_level_to_str(rpmemd->config.log_level));
}
示例#28
0
int
main(int argc, char *argv[])
{
    util_init();

    int send_status = 1;
    int ret = 1;

    struct rpmemd *rpmemd = calloc(1, sizeof(*rpmemd));
    if (!rpmemd) {
        RPMEMD_LOG(ERR, "!calloc");
        goto err_rpmemd;
    }

    rpmemd->obc = rpmemd_obc_init(STDIN_FILENO, STDOUT_FILENO);
    if (!rpmemd->obc) {
        RPMEMD_LOG(ERR, "out-of-band connection intitialization");
        goto err_obc;
    }

    if (rpmemd_log_init(DAEMON_NAME, NULL, 0)) {
        RPMEMD_LOG(ERR, "logging subsystem initialization failed");
        goto err_log_init;
    }

    if (rpmemd_config_read(&rpmemd->config, argc, argv) != 0) {
        RPMEMD_LOG(ERR, "reading configuration failed");
        goto err_config;
    }

    rpmemd_log_close();
    rpmemd_log_level = rpmemd->config.log_level;
    if (rpmemd_log_init(DAEMON_NAME, rpmemd->config.log_file,
                        rpmemd->config.use_syslog)) {
        RPMEMD_LOG(ERR, "logging subsystem initialization"
                   " failed (%s, %d)", rpmemd->config.log_file,
                   rpmemd->config.use_syslog);
        goto err_log_init_config;
    }

    RPMEMD_LOG(INFO, "%s version %s", DAEMON_NAME, SRCVERSION);
    rpmemd->persist = pmem_persist;
    rpmemd->persist_method = rpmemd_get_pm(&rpmemd->config);
    rpmemd->nthreads = rpmemd_get_nthreads();
    if (!rpmemd->nthreads) {
        RPMEMD_LOG(ERR, "invalid number of threads -- '%lu'",
                   rpmemd->nthreads);
        goto err_nthreads;
    }

    rpmemd->db = rpmemd_db_init(rpmemd->config.poolset_dir, 0666);
    if (!rpmemd->db) {
        RPMEMD_LOG(ERR, "!pool set db initialization");
        goto err_db_init;
    }

    if (rpmemd->config.rm_poolset) {
        RPMEMD_LOG(INFO, "removing '%s'",
                   rpmemd->config.rm_poolset);
        if (rpmemd_db_pool_remove(rpmemd->db,
                                  rpmemd->config.rm_poolset,
                                  rpmemd->config.force)) {
            RPMEMD_LOG(ERR, "removing '%s' failed",
                       rpmemd->config.rm_poolset);
        } else {
            RPMEMD_LOG(NOTICE, "removed '%s'",
                       rpmemd->config.rm_poolset);
            ret = 0;
        }
        send_status = 0;
        goto out_rm;
    }

    ret = rpmemd_obc_status(rpmemd->obc, 0);
    if (ret) {
        RPMEMD_LOG(ERR, "writing status failed");
        goto err_status;
    }

    rpmemd_print_info(rpmemd);

    while (!ret) {
        ret = rpmemd_obc_process(rpmemd->obc, &rpmemd_req, rpmemd);
        if (ret) {
            RPMEMD_LOG(ERR, "out-of-band connection"
                       " process failed");
            goto err;
        }

        if (rpmemd->closing)
            break;
    }

    rpmemd_db_fini(rpmemd->db);
    rpmemd_config_free(&rpmemd->config);
    rpmemd_log_close();
    rpmemd_obc_fini(rpmemd->obc);
    free(rpmemd);

    return 0;
err:
    rpmemd_req_cleanup(rpmemd);
err_status:
out_rm:
    rpmemd_db_fini(rpmemd->db);
err_db_init:
err_nthreads:
err_log_init_config:
    rpmemd_config_free(&rpmemd->config);
err_config:
    rpmemd_log_close();
err_log_init:
    if (send_status) {
        if (rpmemd_obc_status(rpmemd->obc, (uint32_t)errno))
            RPMEMD_LOG(ERR, "writing status failed");
    }
    rpmemd_obc_fini(rpmemd->obc);
err_obc:
    free(rpmemd);
err_rpmemd:
    return ret;
}
示例#29
0
/*
 * rpmemd_fip_init -- initialize fabric provider
 */
struct rpmemd_fip *
rpmemd_fip_init(const char *node, const char *service,
	struct rpmemd_fip_attr *attr, struct rpmem_resp_attr *resp,
	enum rpmem_err *err)
{
	int ret;

	RPMEMD_ASSERT(resp);
	RPMEMD_ASSERT(err);
	RPMEMD_ASSERT(attr);
	RPMEMD_ASSERT(attr->persist);
	RPMEMD_ASSERT(attr->nthreads);

	struct rpmemd_fip *fip = calloc(1, sizeof(*fip));
	if (!fip) {
		RPMEMD_LOG(ERR, "!allocating fabric handle");
		*err = RPMEM_ERR_FATAL;
		return NULL;
	}

	ret = rpmemd_fip_getinfo(fip, service, node, attr->provider);
	if (ret) {
		*err = RPMEM_ERR_BADPROVIDER;
		goto err_getinfo;
	}

	rpmemd_fip_set_attr(fip, attr);

	ret = rpmemd_fip_init_fabric_res(fip);
	if (ret) {
		*err = RPMEM_ERR_FATAL;
		goto err_init_fabric_res;
	}

	ret = rpmemd_fip_init_memory(fip);
	if (ret) {
		*err = RPMEM_ERR_FATAL;
		goto err_init_memory;
	}

	ret = fip->ops->init(fip);
	if (ret) {
		*err = RPMEM_ERR_FATAL;
		goto err_init;
	}

	ret = fi_listen(fip->pep);
	if (ret) {
		*err = RPMEM_ERR_FATAL_CONN;
		goto err_fi_listen;
	}

	ret = rpmemd_fip_set_resp(fip, resp);
	if (ret) {
		*err = RPMEM_ERR_FATAL;
		goto err_set_resp;
	}

	return fip;
err_set_resp:
	RPMEMD_FI_CLOSE(fip->pep, "closing passive endpoint");
err_fi_listen:
	fip->ops->fini(fip);
err_init:
	rpmemd_fip_fini_memory(fip);
err_init_memory:
	rpmemd_fip_fini_fabric_res(fip);
err_init_fabric_res:
	fi_freeinfo(fip->fi);
err_getinfo:
	free(fip);
	return NULL;
}
示例#30
0
/*
 * rpmemd_req_open -- handle open request
 */
static int
rpmemd_req_open(struct rpmemd_obc *obc, void *arg,
                const struct rpmem_req_attr *req)
{
    RPMEMD_ASSERT(arg != NULL);
    RPMEMD_LOG(NOTICE, "open request:");
    rpmemd_print_req_attr(req);
    struct rpmemd *rpmemd = (struct rpmemd *)arg;

    int ret;
    int status = 0;
    int err_send = 1;
    struct rpmem_resp_attr resp;
    memset(&resp, 0, sizeof(resp));

    struct rpmem_pool_attr pool_attr;
    memset(&pool_attr, 0, sizeof(pool_attr));

    if (rpmemd->pool) {
        RPMEMD_LOG(ERR, "pool already opened");
        ret = -1;
        status = RPMEM_ERR_FATAL;
        goto err_pool_opened;
    }

    rpmemd->pool_desc = strdup(req->pool_desc);
    if (!rpmemd->pool_desc) {
        RPMEMD_LOG(ERR, "!allocating pool descriptor");
        ret = -1;
        status = RPMEM_ERR_FATAL;
        goto err_strdup;
    }

    rpmemd->pool = rpmemd_db_pool_open(rpmemd->db,
                                       req->pool_desc, 0, &pool_attr);
    if (!rpmemd->pool) {
        ret = -1;
        status = rpmemd_db_get_status(errno);
        goto err_pool_open;
    }

    RPMEMD_LOG(NOTICE, "pool attributes:");
    rpmemd_print_pool_attr(&pool_attr);

    ret = rpmemd_check_pool(rpmemd, req, &status);
    if (ret)
        goto err_pool_check;

    ret = rpmemd_common_fip_init(rpmemd, req, &resp, &status);
    if (ret)
        goto err_fip_init;

    RPMEMD_LOG(NOTICE, "open request response: (status = %u)", status);
    if (!status)
        rpmemd_print_resp_attr(&resp);

    ret = rpmemd_obc_open_resp(rpmemd->obc, status, &resp, &pool_attr);
    if (ret)
        goto err_open_resp;

    ret = rpmemd_fip_start_thread(rpmemd);
    if (ret)
        goto err_fip_start;

    return 0;
err_fip_start:
err_open_resp:
    err_send = 0;
    rpmemd_fip_fini(rpmemd->fip);
err_fip_init:
err_pool_check:
    rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
err_pool_open:
    free(rpmemd->pool_desc);
err_strdup:
err_pool_opened:
    if (err_send)
        ret = rpmemd_obc_open_resp(rpmemd->obc, status,
                                   &resp, &pool_attr);
    rpmemd->closing = 1;
    return ret;
}