示例#1
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;
}
示例#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_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;
}
示例#4
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;
}
示例#5
0
/*
 * parse_cl_args -- (internal) parse command line arguments
 */
static void
parse_cl_args(int argc, char *argv[], struct rpmemd_config *config,
		const char **config_file, uint64_t *cl_options)
{
	RPMEMD_ASSERT(argv != NULL);
	RPMEMD_ASSERT(config != NULL);

	int opt;
	int option_index = 0;

	while ((opt = getopt_long(argc, argv, optstr, options,
		&option_index)) != -1) {

		if (opt == -1)
			break;

		switch (opt) {
		case 'c':
			(*config_file) = optarg;
			break;
		case 'r':
			config->rm_poolset = optarg;
			break;
		case 'h':
			print_help(argv[0]);
			exit(0);
		case 'V':
			print_version();
			exit(0);
			break;
		default:
			if (set_option((enum rpmemd_option)opt, optarg, config)
					== 0) {
				*cl_options |= (uint64_t)(1 << opt);
			} else {
				print_usage(argv[0]);
				exit(-1);
			}
		}
	}
}
示例#6
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;
}
示例#7
0
/*
 * rpmemd_fip_set_attr -- save required attributes in rpmemd_fip handle
 */
static void
rpmemd_fip_set_attr(struct rpmemd_fip *fip, struct rpmemd_fip_attr *attr)
{
	fip->addr = attr->addr;
	fip->size = attr->size;
	fip->nthreads = attr->nthreads;
	fip->persist_method = attr->persist_method;
	fip->persist = attr->persist;

	rpmemd_fip_set_nlanes(fip, attr->nlanes);

	fip->cq_size = rpmem_fip_cq_size(fip->nlanes,
			fip->persist_method,
			RPMEM_FIP_NODE_SERVER);

	RPMEMD_ASSERT(fip->persist_method < MAX_RPMEM_PM);
	fip->ops = &rpmemd_fip_ops[fip->persist_method];
}
示例#8
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;
}
示例#9
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;
}
示例#10
0
/*
 * parse_config_file -- (internal) parse config file
 */
static int
parse_config_file(const char *filename, struct rpmemd_config *config,
	uint64_t disabled)
{
	RPMEMD_ASSERT(filename != NULL);

	FILE *file = fopen(filename, "r");
	if (file == NULL) {
		if (filename != RPMEMD_DEFAULT_CONFIG_FILE) {
			RPMEMD_LOG(ERR, "!%s", filename);
			goto error_fopen;
		} else
			goto default_config_missing;
	}

	uint8_t line_max_increased = 0;
	uint64_t line_max = CONFIG_LINE_SIZE_INIT;
	uint64_t line_num = 1;
	char *line = (char *)malloc(sizeof(char) * line_max);
	if (line == NULL) {
		RPMEMD_LOG(ERR, "!malloc");
		goto error_malloc_line;
	}

	char *line_copy = (char *)malloc(sizeof(char) * line_max);
	if (line_copy == NULL) {
		RPMEMD_LOG(ERR, "!malloc");
		goto error_malloc_line_copy;
	}

	struct rpmemd_special_chars_pos pos;

	do {
		memset(&pos, INT32_MAX, sizeof(pos));
		if (get_config_line(file, &line, &line_max,
			&line_max_increased, &pos) != 0)
			goto error;

		if (line_max_increased) {
			line_copy = (char *)realloc(line_copy,
				sizeof(char) * line_max);
			if (line_copy == NULL) {
				RPMEMD_LOG(ERR, "!malloc");
				goto error_malloc_line_copy;
			}
			line_max_increased = 0;
		}

		if (pos.EOL_char != INVALID_CHAR_POS) {
			strcpy(line_copy, line);
			parse_config_line(line_copy, &pos, config, disabled);
			if (errno != 0) {
				size_t len = strlen(line);
				if (len > 0 && line[len - 1] == '\n')
					line[len - 1] = '\0';
				RPMEMD_LOG(ERR, "Invalid config file line at "
					"%s:%lu\n%s",
					filename, line_num, line);
				goto error;
			}
		}
		++line_num;
	} while (pos.EOL_char != INVALID_CHAR_POS);

	free(line_copy);
	free(line);
	fclose(file);
default_config_missing:
	return 0;

error:
	free(line_copy);
error_malloc_line_copy:
	free(line);
error_malloc_line:
	fclose(file);
error_fopen:
	return -1;
}
示例#11
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "rpmemd_log");

	if (argc < 4) {
		USAGE();
		return 1;
	}

	const char *log_op = argv[1];
	const char *log_type = argv[2];
	const char *file = argv[3];

	int do_fatal = 0;
	int do_assert = 0;
	if (strcmp(log_op, "fatal") == 0) {
		do_fatal = 1;
	} else if (strcmp(log_op, "assert") == 0) {
		do_assert = 1;
	} else if (strcmp(log_op, "log") == 0) {
	} else {
		USAGE();
		return 1;
	}

	enum test_log_type type;
	if (strcmp(log_type, "stdout") == 0) {
		type = TEST_STDOUT;
	} else if (strcmp(log_type, "file") == 0) {
		type = TEST_FILE;
	} else if (strcmp(log_type, "syslog") == 0) {
		type = TEST_SYSLOG;
	} else {
		USAGE();
		return 1;
	}

	int fd_stdout = -1;
	FILE *stdout_fh = NULL;
	switch (type) {
	case TEST_STDOUT:
		/*
		 * Duplicate stdout file descriptor in order to preserve
		 * the file list after redirecting the stdout to a file.
		 */
		fd_stdout = dup(1);
		UT_ASSERTne(fd_stdout, -1);
		close(1);
		stdout_fh = fopen(file, "a");
		UT_ASSERTne(stdout_fh, NULL);
		break;
	case TEST_SYSLOG:
		syslog_fh = fopen(file, "a");
		UT_ASSERTne(syslog_fh, NULL);
		break;
	default:
		break;
	}

	/*
	 * Check an invalid configuration
	 */
	int ret;
	ret = rpmemd_log_init("rpmemd_log", file, 1);
	UT_ASSERTne(ret, 0);

	switch (type) {
	case TEST_STDOUT:
		ret = rpmemd_log_init("rpmemd_log", NULL, 0);
		UT_ASSERTeq(ret, 0);
		break;
	case TEST_SYSLOG:
		ret = rpmemd_log_init("rpmemd_log", NULL, 1);
		UT_ASSERTeq(ret, 0);
		break;
	case TEST_FILE:
		ret = rpmemd_log_init("rpmemd_log", file, 0);
		UT_ASSERTeq(ret, 0);
		break;
	default:
		break;
	}

	if (do_fatal) {
		RPMEMD_FATAL("fatal");
	} else if (do_assert) {
		RPMEMD_ASSERT(1);
		RPMEMD_ASSERT(0);
	} else {
		test_all_log_messages();
	}

	rpmemd_log_close();

	switch (type) {
	case TEST_STDOUT:
		/* restore the original stdout file descriptor */
		fclose(stdout_fh);
		UT_ASSERTeq(dup2(fd_stdout, 1), 1);
		close(fd_stdout);
		break;
	case TEST_SYSLOG:
		fclose(syslog_fh);
		break;
	default:
		break;
	}

	DONE(NULL);
}
示例#12
0
文件: rpmemd.c 项目: gaoning777/nvml
/*
 * 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);

	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");
		status = RPMEM_ERR_FATAL;
		goto err_pool_opened;
	}

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

	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;

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

	ret = rpmemd_fip_accept(rpmemd->fip);
	if (ret) {
		status = RPMEM_ERR_FATAL_CONN;
		goto err_accept;
	}

	ret = rpmemd_fip_process_start(rpmemd->fip);
	if (ret) {
		status = RPMEM_ERR_FATAL_CONN;
		goto err_process_start;
	}

	return 0;
err_process_start:
	rpmemd_fip_close(rpmemd->fip);
err_accept:
	err_send = 0;
err_open_resp:
	rpmemd_fip_fini(rpmemd->fip);
err_fip_init:
err_pool_check:
	rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
err_pool_open:
err_pool_opened:
	if (err_send)
		ret = rpmemd_obc_open_resp(rpmemd->obc, status,
				&resp, &pool_attr);
	rpmemd->closing = 1;
	return ret;
}
示例#13
0
文件: rpmemd.c 项目: gaoning777/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)
{
	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 = rpmemd_get_ssh_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_req_create -- handle create request
 */
static int
rpmemd_req_create(struct rpmemd_obc *obc, void *arg,
	const struct rpmem_req_attr *req,
	const struct rpmem_pool_attr *pool_attr)
{
	RPMEMD_ASSERT(arg != NULL);

	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));

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

	rpmemd->pool = rpmemd_db_pool_create(rpmemd->db,
			req->pool_desc,
			0, (struct rpmem_pool_attr *)pool_attr);

	if (!rpmemd->pool) {
		status = rpmemd_db_get_status(errno);
		goto err_pool_create;
	}

	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;

	ret = rpmemd_obc_create_resp(rpmemd->obc, status, &resp);
	if (ret) {
		err_send = 0;
		goto err_create_resp;
	}

	ret = rpmemd_fip_accept(rpmemd->fip);
	if (ret) {
		status = RPMEM_ERR_FATAL_CONN;
		goto err_accept;
	}

	ret = rpmemd_fip_process_start(rpmemd->fip);
	if (ret) {
		status = RPMEM_ERR_FATAL_CONN;
		goto err_process_start;
	}

	return 0;
err_process_start:
	rpmemd_fip_close(rpmemd->fip);
err_accept:
	err_send = 0;
err_create_resp:
	rpmemd_fip_fini(rpmemd->fip);
err_fip_init:
err_pool_check:
	rpmemd_db_pool_close(rpmemd->db, rpmemd->pool);
	rpmemd_db_pool_remove(rpmemd->db, req->pool_desc);
err_pool_create:
err_pool_opened:
	if (err_send)
		ret = rpmemd_obc_create_resp(rpmemd->obc, status, &resp);
	rpmemd->closing = 1;
	return ret;
}