Esempio n. 1
0
/* loads data from the db */
table_entry_t* load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table)
{
	int int_vals[7];
	char *str_vals[2];
	int no_of_results;
	int i, n;
	int no_rows = 5;
	int db_cols = 10;
	unsigned long last_attempt;
	static db_key_t clusterer_machine_id_key = &machine_id_col;
	static db_val_t clusterer_machine_id_value = {
		.type = DB_INT,
		.nul = 0,
	};

	VAL_INT(&clusterer_machine_id_value) = server_id;

	/* the columns from the db table */
	db_key_t columns[10];
	/* result from a db query */
	db_res_t* res;
	/* a row from the db table */
	db_row_t* row;
	/* the processed result */
	table_entry_t *data;

	res = 0;
	data = 0;

	columns[0] = &cluster_id_col;
	columns[1] = &machine_id_col;
	columns[2] = &state_col;
	columns[3] = &description_col;
	columns[4] = &url_col;
	columns[5] = &id_col;
	columns[6] = &last_attempt_col;
	columns[7] = &failed_attempts_col;
	columns[8] = &no_tries_col;
	columns[9] = &duration_col;

	CON_OR_RESET(db_hdl);

	/* checking if the table version is up to date*/
	if (db_check_table_version(dr_dbf, db_hdl, db_table, 1/*version*/) != 0)
		goto error;

	/* read data */
	if (dr_dbf->use_table(db_hdl, db_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", db_table->len, db_table->s);
		goto error;
	}

	LM_DBG("DB query - retrieve the clusters list"
		"in which the specified server runs\n");

	/* first we see in which clusters the specified server runs*/
	if (dr_dbf->query(db_hdl, &clusterer_machine_id_key, &op_eq,
		&clusterer_machine_id_value, columns, 1, 1, 0, &res) < 0) {
		LM_ERR("DB query failed - cannot retrieve the clusters list in which"
			" the specified server runs\n");
		goto error;
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	if (RES_ROW_N(res) == 0) {
		LM_WARN("No machines found in cluster %d\n", server_id);
		return 0;
	}

	clusterer_cluster_id_key = pkg_realloc(clusterer_cluster_id_key,
		RES_ROW_N(res) * sizeof(db_key_t));
	if (!clusterer_cluster_id_key) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++)
		clusterer_cluster_id_key[i] = &cluster_id_col;

	clusterer_cluster_id_value = pkg_realloc(clusterer_cluster_id_value,
		RES_ROW_N(res) * sizeof(db_val_t));

	if (!clusterer_cluster_id_value) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		VAL_TYPE(clusterer_cluster_id_value + i) = DB_INT;
		VAL_NULL(clusterer_cluster_id_value + i) = 0;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;

		check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0);
		VAL_INT(clusterer_cluster_id_value + i) = VAL_INT(ROW_VALUES(row));
	}

	no_of_results = RES_ROW_N(res);
	dr_dbf->free_result(db_hdl, res);
	res = 0;

	LM_DBG("DB query - retrieve valid connections\n");

	/* fetch is the best strategy */
	CON_USE_OR_OP(db_hdl);
	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {

		if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0,
			clusterer_cluster_id_value, columns, no_of_results, db_cols, 0, 0) < 0) {
			LM_ERR("DB query failed - retrieve valid connections \n");
			goto error;
		}
		no_rows = estimate_available_rows(4 + 4 + 4 + 64 + 4 + 45 + 4 + 8 + 4 + 4, db_cols);
		if (no_rows == 0) no_rows = 5;
		if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0,
			clusterer_cluster_id_value, columns, no_of_results, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed - retrieve valid connections\n");
			goto error;
		}
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	n = 0;
	do {
		for (i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;
			/* CLUSTER ID column */
			check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0);
			int_vals[INT_VALS_CLUSTER_ID_COL] = VAL_INT(ROW_VALUES(row));
			/* MACHINE ID column */
			check_val(machine_id_col, ROW_VALUES(row) + 1, DB_INT, 1, 0);
			int_vals[INT_VALS_MACHINE_ID_COL] = VAL_INT(ROW_VALUES(row) + 1);
			/* STATE column */
			check_val(state_col, ROW_VALUES(row) + 2, DB_INT, 1, 0);
			int_vals[INT_VALS_STATE_COL] = VAL_INT(ROW_VALUES(row) + 2);
			/* DESCRIPTION column */
			check_val(description_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0);
			str_vals[STR_VALS_DESCRIPTION_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 3);
			/* URL column */
			check_val(url_col, ROW_VALUES(row) + 4, DB_STRING, 1, 1);
			str_vals[STR_VALS_URL_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 4);
			/* CLUSTERER_ID column */
			check_val(id_col, ROW_VALUES(row) + 5, DB_INT, 1, 0);
			int_vals[INT_VALS_CLUSTERER_ID_COL] = VAL_INT(ROW_VALUES(row) + 5);
			/* LAST_ATTEMPT column */
			check_val(last_attempt_col, ROW_VALUES(row) + 6, DB_BIGINT, 1, 0);
			last_attempt = VAL_BIGINT(ROW_VALUES(row) + 6);
			/* FAILED_ATTEMPTS column */
			check_val(failed_attempts_col, ROW_VALUES(row) + 7, DB_INT, 1, 0);
			int_vals[INT_VALS_FAILED_ATTEMPTS_COL] = VAL_INT(ROW_VALUES(row) + 7);
			/* NO_TRIES column */
			check_val(no_tries_col, ROW_VALUES(row) + 8, DB_INT, 1, 0);
			int_vals[INT_VALS_NO_TRIES_COL] = VAL_INT(ROW_VALUES(row) + 8);
			/* DURATION column */
			check_val(duration_col, ROW_VALUES(row) + 9, DB_INT, 1, 0);
			int_vals[INT_VALS_DURATION_COL] = VAL_INT(ROW_VALUES(row) + 9);


			/* store data */
			if (add_info(&data, int_vals, last_attempt, str_vals) < 0) {
				LM_DBG("error while adding info to shm\n");
				goto error;
			}

			LM_DBG("machine id %d\n", int_vals[0]);
			LM_DBG("cluster id %d\n", int_vals[1]);
			LM_DBG("state %d\n", int_vals[2]);
			LM_DBG("clusterer_id %d\n", int_vals[3]);
			LM_DBG("description %s\n", str_vals[0]);
			LM_DBG("url %s\n", str_vals[1]);

			n++;
		}
		if (n == 1)
			LM_WARN("The server is the only one in the cluster\n");

		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
				LM_ERR("fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while (RES_ROW_N(res) > 0);

	LM_DBG("%d records found in %.*s\n",
		n, db_table->len, db_table->s);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	return data;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (data)
		free_data(data);
	data = NULL;
	return 0;
}

/* deallocates data */
void free_data(table_entry_t *data)
{
	table_entry_t *tmp_entry;
	table_entry_info_t *info;
	table_entry_info_t *tmp_info;
	table_entry_value_t *value;
	table_entry_value_t *tmp_value;

	struct module_timestamp *timestamp;
	struct module_timestamp *tmp_timestamp;

	while (data != NULL) {
		tmp_entry = data;
		data = data->next;
		info = tmp_entry->info;
		while (info != NULL) {
			value = info->value;
			while (value != NULL) {
				if (value->path.s)
					shm_free(value->path.s);
				if (value->description.s)
					shm_free(value->description.s);
				timestamp = value->in_timestamps;
				while (timestamp != NULL) {
					tmp_timestamp = timestamp;
					timestamp = timestamp->next;
					shm_free(tmp_timestamp);
				}
				tmp_value = value;
				value = value->next;
				shm_free(tmp_value);
			}
			tmp_info = info;
			info = info->next;
			shm_free(tmp_info);
		}
		shm_free(tmp_entry);
	}
}
Esempio n. 2
0
/* loads info from the db */
int load_db_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table,
					cluster_info_t **cl_list)
{
	int int_vals[NO_DB_INT_VALS];
	char *str_vals[NO_DB_STR_VALS];
	int no_clusters;
	int i;
	int rc;
	node_info_t *new_info = NULL;
	db_key_t columns[NO_DB_COLS];	/* the columns from the db table */
	db_res_t *res = NULL;
	db_row_t *row;
	static db_key_t clusterer_node_id_key = &node_id_col;
	static db_val_t clusterer_node_id_value = {
		.type = DB_INT,
		.nul = 0,
	};

	*cl_list = NULL;

	columns[0] = &id_col;
	columns[1] = &cluster_id_col;
	columns[2] = &node_id_col;
	columns[3] = &url_col;
	columns[4] = &state_col;
	columns[5] = &no_ping_retries_col;
	columns[6] = &priority_col;
	columns[7] = &sip_addr_col;
	columns[8] = &flags_col;
	columns[9] = &description_col;

	CON_OR_RESET(db_hdl);

	if (db_check_table_version(dr_dbf, db_hdl, db_table, CLUSTERER_TABLE_VERSION))
		goto error;

	if (dr_dbf->use_table(db_hdl, db_table) < 0) {
		LM_ERR("cannot select table: \"%.*s\"\n", db_table->len, db_table->s);
		goto error;
	}

	LM_DBG("DB query - retrieve the list of clusters"
		" in which the local node runs\n");

	VAL_INT(&clusterer_node_id_value) = current_id;

	/* first we see in which clusters the local node runs*/
	if (dr_dbf->query(db_hdl, &clusterer_node_id_key, &op_eq,
		&clusterer_node_id_value, columns+1, 1, 1, 0, &res) < 0) {
		LM_ERR("DB query failed - cannot retrieve the list of clusters in which"
			" the local node runs\n");
		goto error;
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	if (RES_ROW_N(res) > MAX_NO_CLUSTERS) {
		LM_ERR("Defined: %d clusters for local node, maximum number of clusters "
			"supported(%d) exceeded\n", RES_ROW_N(res), MAX_NO_CLUSTERS);
		goto error;
	}

	if (RES_ROW_N(res) == 0) {
		LM_WARN("No nodes found in cluster\n");
		return 1;
	}

	clusterer_cluster_id_key = pkg_realloc(clusterer_cluster_id_key,
		RES_ROW_N(res) * sizeof(db_key_t));
	if (!clusterer_cluster_id_key) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++)
		clusterer_cluster_id_key[i] = &cluster_id_col;

	clusterer_cluster_id_value = pkg_realloc(clusterer_cluster_id_value,
		RES_ROW_N(res) * sizeof(db_val_t));
	if (!clusterer_cluster_id_value) {
		LM_ERR("no more pkg memory\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		VAL_TYPE(clusterer_cluster_id_value + i) = DB_INT;
		VAL_NULL(clusterer_cluster_id_value + i) = 0;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;
		check_val(cluster_id_col, ROW_VALUES(row), DB_INT, 1, 0);
		VAL_INT(clusterer_cluster_id_value + i) = VAL_INT(ROW_VALUES(row));
	}

	no_clusters = RES_ROW_N(res);
	dr_dbf->free_result(db_hdl, res);
	res = NULL;

	LM_DBG("DB query - retrieve nodes info\n");

	CON_USE_OR_OP(db_hdl);

	if (dr_dbf->query(db_hdl, clusterer_cluster_id_key, 0,
		clusterer_cluster_id_value, columns, no_clusters, NO_DB_COLS, 0, &res) < 0) {
		LM_ERR("DB query failed - retrieve valid connections\n");
		goto error;
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	if (RES_ROW_N(res) > MAX_NO_NODES) {
		LM_ERR("Defined: %d nodes in local node's clusters, maximum number of nodes "
			"supported(%d) exceeded\n", RES_ROW_N(res), MAX_NO_NODES);
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {
		row = RES_ROWS(res) + i;

		check_val(id_col, ROW_VALUES(row), DB_INT, 1, 0);
		int_vals[INT_VALS_ID_COL] = VAL_INT(ROW_VALUES(row));

		check_val(cluster_id_col, ROW_VALUES(row) + 1, DB_INT, 1, 0);
		int_vals[INT_VALS_CLUSTER_ID_COL] = VAL_INT(ROW_VALUES(row) + 1);

		check_val(node_id_col, ROW_VALUES(row) + 2, DB_INT, 1, 0);
		int_vals[INT_VALS_NODE_ID_COL] = VAL_INT(ROW_VALUES(row) + 2);

		check_val(url_col, ROW_VALUES(row) + 3, DB_STRING, 1, 1);
		str_vals[STR_VALS_URL_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 3);

		check_val(state_col, ROW_VALUES(row) + 4, DB_INT, 1, 0);
		int_vals[INT_VALS_STATE_COL] = VAL_INT(ROW_VALUES(row) + 4);

		check_val(no_ping_retries_col, ROW_VALUES(row) + 5, DB_INT, 1, 0);
		int_vals[INT_VALS_NO_PING_RETRIES_COL] = VAL_INT(ROW_VALUES(row) + 5);

		check_val(priority_col, ROW_VALUES(row) + 6, DB_INT, 1, 0);
		int_vals[INT_VALS_PRIORITY_COL] = VAL_INT(ROW_VALUES(row) + 6);

		check_val(sip_addr_col, ROW_VALUES(row) + 7, DB_STRING, 0, 0);
		str_vals[STR_VALS_SIP_ADDR_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 7);

		check_val(flags_col, ROW_VALUES(row) + 8, DB_STRING, 0, 0);
		str_vals[STR_VALS_FLAGS_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 8);

		check_val(description_col, ROW_VALUES(row) + 9, DB_STRING, 0, 0);
		str_vals[STR_VALS_DESCRIPTION_COL] = (char*) VAL_STRING(ROW_VALUES(row) + 9);

		/* add info to backing list */
		if ((rc = add_node_info(&new_info, cl_list, int_vals, str_vals)) != 0) {
			LM_ERR("Unable to add node info to backing list\n");
			if (rc < 0)
				return -1;
			else
				return 2;
		}
	}

	/* warn if no seed node is defined in a cluster */
	check_seed_flag(cl_list);

	if (RES_ROW_N(res) == 1)
		LM_INFO("The local node is the only one in the cluster\n");

	dr_dbf->free_result(db_hdl, res);

	return 0;
error:
	if (res)
		dr_dbf->free_result(db_hdl, res);
	if (*cl_list)
		free_info(*cl_list);
	*cl_list = NULL;
	return -1;
}

int provision_neighbor(modparam_t type, void *val)
{
	int int_vals[NO_DB_INT_VALS];
	char *str_vals[NO_DB_STR_VALS];
	str prov_str;
	node_info_t *new_info;

	if (db_mode) {
		LM_INFO("Running in db mode, provisioning from the script is ignored\n");
		return 0;
	}

	prov_str.s = (char*)val;
	prov_str.len = strlen(prov_str.s);

	if (parse_param_node_info(&prov_str, int_vals, str_vals) < 0) {
		LM_ERR("Unable to define a neighbor node\n");
		return -1;
	}

	if (int_vals[INT_VALS_CLUSTER_ID_COL] == -1 ||
		int_vals[INT_VALS_NODE_ID_COL] == -1 ||
		str_vals[STR_VALS_URL_COL] == NULL) {
		LM_ERR("At least the cluster id, node id and url are required for a neighbor node\n");
		return -1;
	}
	int_vals[INT_VALS_STATE_COL] = 1;
	if (int_vals[INT_VALS_NO_PING_RETRIES_COL] == -1)
		int_vals[INT_VALS_NO_PING_RETRIES_COL] = DEFAULT_NO_PING_RETRIES;
	if (int_vals[INT_VALS_PRIORITY_COL] == -1)
		int_vals[INT_VALS_PRIORITY_COL] = DEFAULT_NO_PING_RETRIES;

	str_vals[STR_VALS_DESCRIPTION_COL] = NULL;
	int_vals[INT_VALS_ID_COL] = -1;

	if (cluster_list == NULL) {
		cluster_list = shm_malloc(sizeof *cluster_list);
		if (!cluster_list) {
			LM_CRIT("No more shm memory\n");
			return -1;
		}
		*cluster_list = NULL;
	}

	if (add_node_info(&new_info, cluster_list, int_vals, str_vals) < 0) {
		LM_ERR("Unable to add node info to backing list\n");
		return -1;
	}

	return 0;
}