示例#1
0
文件: check.c 项目: Inkvi/elliptics
int dnet_check(struct dnet_node *n, struct dnet_meta_container *mc, struct dnet_bulk_array *bulk_array,
		int need_merge, struct dnet_check_params *params)
{
	int err = 0;
	struct dnet_session *s = dnet_session_create(n);
	dnet_session_set_groups(s, (int *)&n->id.group_id, 1);

	dnet_log(n, DNET_LOG_DEBUG, "need_merge = %d, mc.size = %d\n", need_merge, mc->size);
	if (need_merge) {
		err = dnet_check_merge(s, mc);
		dnet_log(n, DNET_LOG_DEBUG, "err=%d\n", err);
		if (!err)
			dnet_merge_remove_local(n, &mc->id, 0);
	} else {
		err = dnet_check_copies(n, mc, bulk_array, params);
	}
	return err;
}
示例#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);
}
示例#3
0
文件: check.c 项目: Inkvi/elliptics
static int dnet_bulk_check_complete_single(struct dnet_net_state *state, struct dnet_bulk_id *ids,
						int remote_group, struct dnet_bulk_check_priv *p)
{
	struct dnet_session *s = dnet_session_create(state->n);
	struct dnet_meta_container mc;
	struct dnet_meta_container temp_mc;
	struct dnet_meta_update *mu;
	struct dnet_meta *mg;
	struct dnet_id id;
	char *tmpdata = NULL;
	int *groups, group_num = 1;
	int err = -EINVAL, error = 0;
	int i = 0;
	int my_group, lastest_group = -1;
	struct dnet_meta_update lastest_mu, my_mu;
	struct timeval current_ts;
	int removed_in_all = 1, updated = 0;
	int lastest = 0;
	uint64_t cflags = 0;
	uint64_t ioflags = 0;


	my_group = state->n->id.group_id;

	dnet_log(state->n, DNET_LOG_DEBUG, "BULK: checking ID %s\n", dnet_dump_id_str(ids->id.id));
	err = -ENOENT;
	error = 0;

	dnet_setup_id(&mc.id, my_group, ids->id.id);

	err = state->n->cb->meta_read(state->n->cb->command_private, &ids->id, &mc.data);
	if (err <= 0) {
		if (err == 0)
			err = -ENOENT;
		goto err_out_continue;
	}
	mc.size = err;

	/* Set current group meta_update as lastest_mu */
	if (!dnet_get_meta_update(state->n, &mc, &my_mu)) {
		dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: meta_update structure doesn't exist for group %d\n",
				dnet_dump_id_str(ids->id.id), my_group);
		err = -ENOENT;
		goto err_out_kcfree;
	}
	dnet_convert_meta_update(&my_mu);
	memcpy(&lastest_mu, &my_mu, sizeof(struct dnet_meta_update));
	lastest_group = my_group;

	/* Get group list */
	if (p->group_num) {
		/* groups came from dnet_check utility */
		groups = p->groups;
		group_num = p->group_num;
	} else {
		mg = dnet_meta_search(state->n, &mc, DNET_META_GROUPS);
		if (!mg) {
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: DNET_META_GROUPS structure doesn't exist\n", dnet_dump_id_str(ids->id.id));
			err = -ENOENT;
			goto err_out_kcfree;
		}
		dnet_convert_meta(mg);
		if (mg->size % sizeof(int)) {
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: DNET_META_GROUPS structure is corrupted\n", dnet_dump_id_str(ids->id.id));
			err = -1;
			goto err_out_kcfree;
		}
		group_num = mg->size / sizeof(int);
		groups = (int *)mg->data;
		dnet_convert_meta(mg);
	}

	/* Read temporary meta */
	temp_mc.data = malloc(sizeof(struct dnet_meta_update) * group_num);
	if (!temp_mc.data) {
		err = -ENOMEM;
		dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: could not allocate memory for temp UPDATE_META\n", dnet_dump_id_str(ids->id.id));
		goto err_out_kcfree;
	}
	memset(temp_mc.data, 0, sizeof(struct dnet_meta_update) * group_num);
	temp_mc.size = sizeof(struct dnet_meta_update) * group_num;

	err = dnet_db_read_raw(p->db->b, &ids->id, (void **)&tmpdata);
	if (err <= 0) {
		if (err < 0 && err != -2)
			goto err_out_free;
		/* No data in temp meta was stored. Placing local meta_update at the beginning */
		mu = temp_mc.data;
		mu[0].group_id = my_group;
		mu[0].tm = my_mu.tm;
		mu[0].flags = my_mu.flags;
		
	} else {
		if (err > (int)(sizeof(struct dnet_meta_update) * group_num)) {
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: too many data stored in temp meta\n",  dnet_dump_id_str(ids->id.id));
			err = -ENOMEM;
			goto err_out_free;
		}
		memcpy(temp_mc.data, tmpdata, err);
	}

	/* Update temp meta with received group */
	mu = temp_mc.data;
	updated = 0;
	lastest = 0;
	for (i = 0; i < group_num; ++i) {
		if (mu[i].group_id == remote_group) {
			mu[i].tm = ids->last_update.tm;
			mu[i].flags = ids->last_update.flags;
			updated = 1;
		}

		if (mu[i].group_id == 0)
			break;

		if (!(mu[i].flags & DNET_IO_FLAGS_REMOVED))
			removed_in_all = 0;

		if (((mu[i].tm.tsec > mu[lastest].tm.tsec)
				|| ((mu[i].tm.tsec == mu[lastest].tm.tsec) && (mu[i].tm.tnsec > mu[lastest].tm.tnsec)))
			&& i != lastest) {
			lastest = i;
			lastest_group = groups[i];
		}
	
	}
	if (!updated && i == group_num) {
		dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: no space left to save group in temp meta!\n", dnet_dump_id_str(ids->id.id));
		err = -ENOMEM;
		goto err_out_free;
	}
	if (!updated) {
		mu[i].group_id = remote_group;
		mu[i].tm = ids->last_update.tm;
		mu[i].flags = ids->last_update.flags;

		if (((mu[i].tm.tsec > mu[lastest].tm.tsec)
				|| ((mu[i].tm.tsec == mu[lastest].tm.tsec) && (mu[i].tm.tnsec > mu[lastest].tm.tnsec)))
			&& i != lastest) {
			lastest = i;
			lastest_group = groups[i];
		}

		++i;
	}

	/* Not all groups processed yet */
	if (i < group_num) {
		err = 0;
		err = dnet_db_write_raw(p->db->b, &ids->id, temp_mc.data, temp_mc.size);
		if (err) {
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: unable to save temp meta, err: %d\n", dnet_dump_id_str(ids->id.id), err);
		}
		goto err_out_free;
	}

	/* Check if removal_delay second has gone since object was marked as REMOVED */
	if (removed_in_all) {
		gettimeofday(&current_ts, NULL);
		if (((uint64_t)current_ts.tv_sec < mu[lastest].tm.tsec) 
			|| ((uint64_t)current_ts.tv_sec - mu[lastest].tm.tsec) < (uint64_t)(state->n->removal_delay * 3600 * 24))
			removed_in_all = 0;
	}

	/* TODO: receive newer files from remote groups
	 *
	 * Yep, we should read it locally and send it to other groups too
	 */
	if ((lastest_group != my_group) && !(mu[lastest].flags & DNET_IO_FLAGS_REMOVED)) {
		dnet_log(state->n, DNET_LOG_DEBUG, "BULK: %s: File on remote group %d is newer, skipping this file\n",
				dnet_dump_id_str(ids->id.id), lastest_group);
		err = 0;
		goto err_out_free;
	}

	for (i = 0; i < group_num; ++i) {
		err = 0;
		if (mu[i].group_id == my_group)
			continue;

		dnet_session_set_groups(s, (int *)&mu[i].group_id, 1);
		dnet_setup_id(&id, mu[i].group_id, ids->id.id);
		id.type = -1;

		if (mu[lastest].flags & DNET_IO_FLAGS_REMOVED) {
			if (removed_in_all) {
				dnet_log(state->n, DNET_LOG_DEBUG, "BULK: dnet_remove_object_now %s in group %d, err=%d\n",
						dnet_dump_id(&id), mu[i].group_id, err);
				err = dnet_remove_object_now(s, &id, cflags, ioflags);
			} else {
				if (!(mu[i].flags & DNET_IO_FLAGS_REMOVED)) {
					err = dnet_remove_object(s, &id, NULL, NULL, cflags, ioflags);
					dnet_log(state->n, DNET_LOG_DEBUG, "BULK: dnet_remove_object %s in group %d err=%d\n",
							dnet_dump_id(&id), mu[i].group_id, err);
				}
			}
			if (err < 0)
				goto err_out_cont2;
		} else {
			if ((mu[i].tm.tsec < mu[lastest].tm.tsec) || ((mu[i].tm.tsec == mu[lastest].tm.tsec) &&
									((mu[i].tm.tnsec < mu[lastest].tm.tnsec)))) {
				err = state->n->cb->send(state, state->n->cb->command_private, &id);

				if (err)
					goto err_out_cont2;

				err = dnet_meta_update_check_status_raw(state->n, &mc);
				if (err)
					goto err_out_cont2;

				memcpy(&mc.id, &id, sizeof(struct dnet_id));
				err = dnet_write_metadata(s, &mc, 1, cflags);
				dnet_log(state->n, DNET_LOG_DEBUG, "BULK: dnet_write_metadata %s in group %d, err=%d\n",
						dnet_dump_id(&id), my_group, err);

				if (err < 0)
					goto err_out_cont2;
			}
		}
err_out_cont2:
		if (err < 0)
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: Error during sending transaction to group %d, err=%d\n",
					dnet_dump_id_str(ids->id.id), groups[i], err);
		if (!error && err < 0)
			error = err;
	}

	if (mu[lastest].flags & DNET_IO_FLAGS_REMOVED) {
		if (removed_in_all) {
			err = dnet_merge_remove_local(state->n, &mc.id, 0);
		} else if (!(my_mu.flags & DNET_IO_FLAGS_REMOVED)) {
			err = dnet_merge_remove_local(state->n, &mc.id, 1);
		}
	}

	if (!(mu[lastest].flags & DNET_IO_FLAGS_REMOVED) && !error) {
		err = dnet_meta_update_check_status(state->n, &mc);
		if (err) {
			dnet_log(state->n, DNET_LOG_ERROR, "BULK: %s: couldn't update meta CHECK_STATUS\n", dnet_dump_id_str(ids->id.id));
		}
	}

	if (group_num > 2) {
		err = dnet_db_remove_raw(p->db->b, &ids->id, 1);
		if (!err) {
			dnet_log_raw(state->n, DNET_LOG_ERROR, "BULK: %s: DB: failed to remove temp_meta object, err: %d.\n",
				dnet_dump_id(&mc.id), err);
		}
	}

	if (error > 0)
		error = 0;
err_out_free:
	free(temp_mc.data);
err_out_kcfree:
	free(mc.data);
	if (tmpdata)
		free(tmpdata);
err_out_continue:
	if (error < 0) {
		dnet_log(state->n, DNET_LOG_ERROR, "Failed to check ID %s to %s, err=%d\n", dnet_dump_id_str(ids->id.id),
				dnet_state_dump_addr(state), error);
	}
	if (i == group_num) {
		dnet_counter_inc(state->n, DNET_CNTR_NODE_CHECK_COPY, error);
	}

	return error;
}
示例#4
0
文件: stat.c 项目: Inkvi/elliptics
int main(int argc, char *argv[])
{
	int ch, err, i, have_remote = 0;
	struct dnet_node *n = NULL;
	struct dnet_session *s = NULL;
	struct dnet_config cfg, rem;
	int max_id_idx = 1000, id_idx = 0;
	int timeout;
	unsigned char id[max_id_idx][DNET_ID_SIZE];
	char *logfile = "/dev/stderr", *statfile = "/dev/stdout";
	FILE *log = NULL, *stat;

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

	cfg.sock_type = SOCK_STREAM;
	cfg.proto = IPPROTO_TCP;
	cfg.wait_timeout = 60*60;
	stat_logger.log_level = DNET_LOG_ERROR;

	timeout = 1;

	memcpy(&rem, &cfg, sizeof(struct dnet_config));

	while ((ch = getopt(argc, argv, "MFAt:m:w:l:I:r:h")) != -1) {
		switch (ch) {
			case 'M':
				stat_mem = 1;
				break;
			case 'F':
				stat_fs = 1;
				break;
			case 'A':
				stat_la = 1;
				break;
			case 't':
				timeout = atoi(optarg);
				break;
			case 'm':
				stat_logger.log_level = strtoul(optarg, NULL, 0);
				break;
			case 'w':
				cfg.wait_timeout = atoi(optarg);
				break;
			case 'L':
				statfile = optarg;
				break;
			case 'l':
				logfile = optarg;
				break;
			case 'I':
				if (id_idx < max_id_idx) {
					err = dnet_parse_numeric_id(optarg, id[id_idx]);
					if (err)
						return err;
					id_idx++;
				}
				break;
			case 'r':
				err = dnet_parse_addr(optarg, &rem);
				if (err)
					return err;
				have_remote = 1;
				break;
			case 'h':
			default:
				stat_usage(argv[0]);
				return -1;
		}
	}

	if (!have_remote) {
		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;
	}

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

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

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

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

	err = dnet_add_state(n, &rem);
	if (err)
		return err;

	while (1) {
		struct dnet_id raw;

		if (!id_idx) {
			err = dnet_request_stat(s, NULL, DNET_CMD_STAT, 0, stat_complete, stat);
			if (err < 0)
				return err;
		}

		for (i=0; i<id_idx; ++i) {
			dnet_setup_id(&raw, 0, id[i]);
			err = dnet_request_stat(s, &raw, DNET_CMD_STAT, 0, stat_complete, stat);
			if (err < 0)
				return err;
		}

		sleep(timeout);
	}

	return 0;
}