예제 #1
0
extern "C" struct dnet_node *dnet_parse_config(const char *file, int mon)
{
	dnet_node *node = NULL;
	config_data *data = NULL;

	try {
		data = static_cast<config_data *>(dnet_config_data_create());
		if (!data)
			throw std::bad_alloc();

		data->config_path = file;

		auto parser = data->parse_config();
		const config root = parser->root();
		const config logger = root.at("logger");
		const config options = root.at("options");
		const config backends = root.at("backends");

		parse_logger(data, logger);
		parse_options(data, options);
		parse_backends(data, backends);

		if (data->daemon_mode && !mon)
			dnet_background();

		if (!data->cfg_addr_num)
			throw config_error("no local address specified, exiting");

		node = dnet_server_node_create(data);
		if (!node)
			throw config_error("failed to create node");

		static_assert(sizeof(dnet_addr) == sizeof(address), "Size of dnet_addr and size of address must be equal");
		if (data->remotes.size() != 0) {
			int err = dnet_add_state(node, reinterpret_cast<const dnet_addr *>(data->remotes.data()), data->remotes.size(), 0);
			if (err < 0)
				BH_LOG(*node->log, DNET_LOG_WARNING, "Failed to connect to remote nodes: %d", err);
		}

	} catch (std::exception &exc) {
		if (data && data->cfg_state.log) {
			dnet_backend_log(data->cfg_state.log, DNET_LOG_ERROR,
				"cnf: failed to read config file '%s': %s", file, exc.what());
		} else {
			fprintf(stderr, "cnf: %s\n", exc.what());
			fflush(stderr);
		}

		if (node)
			dnet_server_node_destroy(node);
		else if (data)
			dnet_config_data_destroy(data);

		return NULL;
	}

	return node;
}
예제 #2
0
파일: check.c 프로젝트: itroot/elliptics
int main(int argc, char *argv[])
{
	int ch, err;
	struct dnet_node *n = NULL;
	struct dnet_config cfg;
	char *remote_addr = NULL;
	int remote_port = -1;
	int remote_family = -1;
	char *logfile = default_log;
	int daemonize = 0;
	FILE *log = NULL;
	struct dnet_check_request r, *req, *req2;
	struct tm tm;
	char *file = NULL;
	int group_num = 0, *groups;
	char *ns = NULL;
	int nsize = 0;
	struct dnet_session *s;

	memset(&cfg, 0, sizeof(struct dnet_config));

	cfg.wait_timeout = INT_MAX;
	check_logger.log_level = DNET_LOG_INFO;
	cfg.check_timeout = 60;

	memset(&tm, 0, sizeof(tm));

	memset(&r, 0, sizeof(r));

	r.thread_num = 1;

	while ((ch = getopt(argc, argv, "b:B:DN:f:n:t:u:U:MRm:w:l:dr:g:h")) != -1) {
		switch (ch) {
			case 'b':
				r.blob_start = atoi(optarg);
				break;
			case 'B':
				r.blob_num = atoi(optarg);
				break;
			case 'N':
				ns = optarg;
				nsize = strlen(optarg);
				break;
			case 'f':
				file = optarg;
				break;
			case 'n':
				r.thread_num = atoi(optarg);
				if (r.thread_num > 1)
					fprintf(stderr, "You are going to run your recovery process with %d threads, "
							"this can heavily screw up your system performance.\n", r.thread_num);
				break;
			case 't':
				if (!strptime(optarg, "%F %T", &tm)) {
					fprintf(stderr, "Invalid timestamp string in -t\n");
					check_usage(argv[0]);
					return -EINVAL;
				}
				r.timestamp = mktime(&tm);
				break;
			case 'u':
				if (!strptime(optarg, "%F %T", &tm)) {
					fprintf(stderr, "Invalid timestamp string in -u\n");
					check_usage(argv[0]);
					return -EINVAL;
				}
				r.updatestamp_start = mktime(&tm);
				break;
			case 'U':
				if (!strptime(optarg, "%F %T", &tm)) {
					fprintf(stderr, "Invalid timestamp string in -U\n");
					check_usage(argv[0]);
					return -EINVAL;
				}
				r.updatestamp_stop = mktime(&tm);
				break;
			case 'D':
				r.flags |= DNET_CHECK_DRY_RUN;
				break;
			case 'M':
				r.flags |= DNET_CHECK_MERGE;
				break;
//			case 'F':
//				r.flags |= DNET_CHECK_FULL;
//				break;
			case 'R':
				r.flags |= DNET_CHECK_DELETE;
				break;
			case 'm':
				check_logger.log_level = strtoul(optarg, NULL, 0);
				break;
			case 'w':
				cfg.check_timeout = cfg.wait_timeout = atoi(optarg);
				break;
			case 'l':
				logfile = optarg;
				break;
			case 'd':
				daemonize = 1;
				break;
			case 'r':
				err = dnet_parse_addr(optarg, &remote_port, &remote_family);
				if (err)
					return err;
				remote_addr = optarg;
				break;
			case 'g':
				group_num = dnet_parse_groups(optarg, &groups);
				if (group_num <= 0)
					return -1;
				break;
			case 'h':
			default:
				check_usage(argv[0]);
				return -1;
		}
	}

	if (!remote_addr) {
		fprintf(stderr, "No remote node specified to route requests.\n");
		return -ENOENT;
	}

	log = fopen(logfile, "a");
	if (!log) {
		err = -errno;
		fprintf(stderr, "Failed to open log file %s: %s.\n", logfile, strerror(errno));
		return err;
	}

	if (daemonize) {
		if (logfile == default_log) {
			fprintf(stderr, "You should specify log file for daemon mode\n");
		} else {
			dnet_background();
		}
	}

	check_logger.log_private = log;
	check_logger.log = dnet_common_log;
	cfg.log = &check_logger;

	n = dnet_node_create(&cfg);
	if (!n)
		return -1;

	err = dnet_add_state(n, remote_addr, remote_port, remote_family, DNET_CFG_NO_ROUTE_LIST);
	if (err)
		return err;

	s = dnet_session_create(n);
	if (!s)
		return -ENOMEM;

	err = dnet_session_set_ns(s, ns, nsize);
	if (err)
		return err;

	req = &r;
	if (file) {
		req = dnet_check_gen_request(s, &r, file);
		if (!req)
			return -EINVAL;
	}

	if (group_num > 0) {
		req2 = malloc(sizeof(struct dnet_check_request) + req->obj_num * sizeof(struct dnet_id) + group_num * sizeof(int));
		if (!req2)
			return -ENOMEM;

		memcpy(req2, req, sizeof(struct dnet_check_request) + req->obj_num * sizeof(struct dnet_id));
		memcpy((char *)req2 + sizeof(struct dnet_check_request) + req->obj_num * sizeof(struct dnet_id), groups,
				group_num * sizeof(int));
		req2->group_num = group_num;

		req = req2;
	}

	return dnet_request_check(s, req);
}