Example #1
0
/*
 * RPC command to dump pkg summary to syslog
 */
static void corex_rpc_pkg_summary(rpc_t* rpc, void* c)
{
	str	group = str_init("core");
	str var = str_init("mem_dump_pkg");
	str sel = {0, 0};
	int	i;

	if (rpc->scan(c, "Sd", &sel, &i) < 2) {
		rpc->fault(c, 400, "Selector and value not provided");
		return;
	}

	if(sel.len!=3) {
		rpc->fault(c, 500, "Unsupported selector");
		return;
	}

	if(strncasecmp(sel.s, "idx", 3)==0) {
		if(i<0 || i>=*process_count) {
			rpc->fault(c, 500, "Index value out of range");
			return;
		}
		i = pt[i].pid;
	} else if(strncasecmp(sel.s, "pid", 3)!=0) {
		rpc->fault(c, 500, "Unsupported selector type");
		return;
	}

	if(cfg_set_now(_cfg_corex_ctx, &group, NULL, &var,
				(void *)(long)i, CFG_VAR_INT)!=0) {
		rpc->fault(c, 500, "Operation failed");
		return;
	}
}
Example #2
0
static struct mi_root *mi_debug(struct mi_root *cmd, void *param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node;
	char *p;
	int len;
	int new_debug = 0;
	str group_name = {"core", 4};
	str var_name = {"debug", 5};
	void *vval = 0;
	int set = 0;
	unsigned int val_type;

	node = cmd->node.kids;
	if (node!=NULL) {
		if (str2sint( &node->value, &new_debug) < 0)
			return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
		set = 1;
	} else {
		if(cfg_get_by_name(_kex_cfg_ctx, &group_name, NULL /* group id */, &var_name, &vval,
					&val_type)!=0)
			return init_mi_tree( 500, MI_SSTR(MI_INTERNAL_ERR));
		new_debug = (int)(long)vval;
	}
	rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
	if (rpl_tree==0)
		return 0;

	p = sint2str((long)new_debug, &len);
	node = add_mi_node_child( &rpl_tree->node, MI_DUP_VALUE,
		MI_SSTR("DEBUG"),p, len);
	if (node==0) {
		free_mi_tree(rpl_tree);
		return 0;
	}

	if(set==1) {
		cfg_set_now(_kex_cfg_ctx, &group_name, NULL /* group id */, &var_name,
				(void *)(long)new_debug, CFG_VAR_INT);
	}

	return rpl_tree;
}
Example #3
0
/* translate name using translation table, returns 0..not found, 1..success, -1..error */
static int find_cfg_var(str *group_name, char *def_name, db_res_t *transl_res) {
	
	db_rec_t *transl_rec;
	int ret = -1;

	DBG(MODULE_NAME": find_cfg_var('%.*s', '%s', ...)\n", group_name->len, group_name->s, def_name);
	transl_rec = db_first(transl_res);
	/* iterate through each candidate where cfg def may be found */
	while (transl_rec) {

		static db_cmd_t* cmd;
		db_rec_t *rec;
		db_res_t *res;
		db_fld_t params[3], cols[2];
		
		memset(cols, 0, sizeof(cols));
		cols[0].name = GETCSTR(transl_rec->fld[3], def_cfg_table_value_field);
		cols[0].type = DB_NONE;
		
		memset(params, 0, sizeof(params));
		params[0].name = GETCSTR(transl_rec->fld[1], def_cfg_table_group_name_field);
		params[0].type = DB_STR;
		params[0].op = DB_EQ;
		params[1].name = GETCSTR(transl_rec->fld[2], def_cfg_table_name_field);
		params[1].type = DB_CSTR;
		params[1].op = DB_EQ;

		DBG(MODULE_NAME": exec_transl: looking in '%s'\n", GETCSTR(transl_rec->fld[0], def_cfg_table));
		cmd = db_cmd(DB_GET, db_cntx, GETCSTR(transl_rec->fld[0], def_cfg_table), cols, params, NULL);
		if (!cmd) {
			ERR(MODULE_NAME": Error preparing query '%s'\n", transl_tbl);
			return -1;		
		}
		cmd->match[0].flags &= ~DB_NULL;
		cmd->match[0].v.lstr = *group_name;
		cmd->match[1].flags &= ~DB_NULL;
		cmd->match[1].v.cstr = def_name;
									
		// FIXME: proprietary code!
		db_setopt(cmd, "key", "bySerGroup");
		db_setopt(cmd, "key_omit", 0);
		
		if (db_exec(&res, cmd) < 0) {
			ERR(MODULE_NAME": Error executing query '%s'\n", transl_tbl);
			db_cmd_free(cmd);
			return -1;
		}
	
		rec = db_first(res);
		if (rec) { /* var found in config table */
			str def_name_s;
			def_name_s.s = def_name;
			def_name_s.len = strlen(def_name);
			DBG(MODULE_NAME": exec_transl: found record, type:%d\n", rec->fld[0].type);
			/* read and set cfg var */
			switch (rec->fld[0].type) {
				case DB_STR:
					if (cfg_set_now(cfg_ctx, group_name, NULL /* group id */, &def_name_s, &rec->fld[0].v.lstr, CFG_VAR_STR) < 0) goto err;
					break;
				case DB_CSTR:					
					if (cfg_set_now_string(cfg_ctx, group_name, NULL /* group id */, &def_name_s, rec->fld[0].v.cstr) < 0) goto err;
					break;
				case DB_INT:
					if (cfg_set_now_int(cfg_ctx, group_name, NULL /* group id */, &def_name_s, rec->fld[0].v.int4) < 0) goto err;
					break;
				default:
					ERR(MODULE_NAME": unexpected field type (%d), table:'%s', field:'%s'\n", 
						rec->fld[0].type, 
						GETCSTR(transl_rec->fld[0], def_cfg_table), 
						GETCSTR(transl_rec->fld[3], def_cfg_table_value_field)
					);
					goto err;
			}
			ret = 1;
		err:
			db_res_free(res);
			db_cmd_free(cmd);
			return ret;
		}
		db_res_free(res);
		db_cmd_free(cmd);
		
		transl_rec = db_next(transl_res);	
	}
	return 0;
}
Example #4
0
/* sets the value of a variable but does not commit the change
 *
 * return value:
 *   0: success
 *  -1: error
 *   1: variable has not been found
 */
int cfg_set_delayed(cfg_ctx_t *ctx, str *group_name, str *var_name,
			void *val, unsigned int val_type)
{
	cfg_group_t	*group;
	cfg_mapping_t	*var;
	void		*v;
	char		*temp_handle;
	int		temp_handle_created;
	cfg_changed_var_t	*changed = NULL;
	int		size;
	str		s;

	if (!cfg_shmized)
		/* the cfg has not been shmized yet, there is no
		point in registering the change and committing it later */
		return cfg_set_now(ctx, group_name, var_name,
					val, val_type);

	if (!ctx) {
		LOG(L_ERR, "ERROR: cfg_set_delayed(): context is undefined\n");
		return -1;
	}

	/* look-up the group and the variable */
	if (cfg_lookup_var(group_name, var_name, &group, &var))
		return 1;

	/* check whether the variable is read-only */
	if (var->def->type & CFG_READONLY) {
		LOG(L_ERR, "ERROR: cfg_set_delayed(): variable is read-only\n");
		goto error0;
	}

	/* check whether we have to convert the type */
	if (convert_val(val_type, val, CFG_INPUT_TYPE(var), &v))
		goto error0;

	if ((CFG_INPUT_TYPE(var) == CFG_INPUT_INT) 
	&& (var->def->min || var->def->max)) {
		/* perform a simple min-max check for integers */
		if (((int)(long)v < var->def->min)
		|| ((int)(long)v > var->def->max)) {
			LOG(L_ERR, "ERROR: cfg_set_delayed(): integer value is out of range\n");
			goto error0;
		}
	}

	/* the ctx must be locked while reading and writing
	the list of changed variables */
	CFG_CTX_LOCK(ctx);

	if (var->def->on_change_cb) {
		/* The fixup function must see also the
		not yet committed values, so a temporary handle
		must be prepared that points to the new config.
		Only the values within the group are applied,
		other modifications are not visible to the callback.
		The local config is the base. */

		if (ctx->changed_first) {
			temp_handle = (char *)pkg_malloc(group->size);
			if (!temp_handle) {
				LOG(L_ERR, "ERROR: cfg_set_delayed(): "
					"not enough memory\n");
				goto error;
			}
			temp_handle_created = 1;
			memcpy(temp_handle, *(group->handle), group->size);

			/* apply the changes */
			for (	changed = ctx->changed_first;
				changed;
				changed = changed->next
			) {
				if (changed->group != group) continue;

				memcpy(	temp_handle + changed->var->offset,
					changed->new_val.vraw,
					cfg_var_size(changed->var));
			}
		} else {
			/* there is not any change */
			temp_handle = *(group->handle);
			temp_handle_created = 0;
		}
			
		if (var->def->on_change_cb(temp_handle,
						group_name,
						var_name,
						&v) < 0) {
			LOG(L_ERR, "ERROR: cfg_set_delayed(): fixup failed\n");
			if (temp_handle_created) pkg_free(temp_handle);
			goto error;
		}
		if (temp_handle_created) pkg_free(temp_handle);

	}

	/* everything went ok, we can add the new value to the list */
	size = sizeof(cfg_changed_var_t) -
			sizeof(((cfg_changed_var_t*)0)->new_val) + cfg_var_size(var);
	changed = (cfg_changed_var_t *)shm_malloc(size);
	if (!changed) {
		LOG(L_ERR, "ERROR: cfg_set_delayed(): not enough shm memory\n");
		goto error;
	}
	memset(changed, 0, size);
	changed->group = group;
	changed->var = var;

	switch (CFG_VAR_TYPE(var)) {

	case CFG_VAR_INT:
		changed->new_val.vint = (int)(long)v;
		break;

	case CFG_VAR_STRING:
		/* clone the string to shm mem */
		s.s = v;
		s.len = (s.s) ? strlen(s.s) : 0;
		if (cfg_clone_str(&s, &s)) goto error;
		changed->new_val.vp = s.s;
		break;

	case CFG_VAR_STR:
		/* clone the string to shm mem */
		s = *(str *)v;
		if (cfg_clone_str(&s, &s)) goto error;
		changed->new_val.vstr=s;
		break;

	case CFG_VAR_POINTER:
		changed->new_val.vp=v;
		break;

	}

	/* Add the new item to the end of the linked list,
	The commit will go though the list from the first item,
	so the list is kept in order */
	if (ctx->changed_first)
		ctx->changed_last->next = changed;
	else
		ctx->changed_first = changed;

	ctx->changed_last = changed;

	CFG_CTX_UNLOCK(ctx);

	if (val_type == CFG_VAR_INT)
		LOG(L_INFO, "INFO: cfg_set_delayed(): %.*s.%.*s "
			"is going to be changed to %d "
			"[context=%p]\n",
			group_name->len, group_name->s,
			var_name->len, var_name->s,
			(int)(long)val,
			ctx);

	else if (val_type == CFG_VAR_STRING)
		LOG(L_INFO, "INFO: cfg_set_delayed(): %.*s.%.*s "
			"is going to be changed to \"%s\" "
			"[context=%p]\n",
			group_name->len, group_name->s,
			var_name->len, var_name->s,
			(char *)val,
			ctx);

	else /* str type */
		LOG(L_INFO, "INFO: cfg_set_delayed(): %.*s.%.*s "
			"is going to be changed to \"%.*s\" "
			"[context=%p]\n",
			group_name->len, group_name->s,
			var_name->len, var_name->s,
			((str *)val)->len, ((str *)val)->s,
			ctx);

	convert_val_cleanup();
	return 0;

error:
	CFG_CTX_UNLOCK(ctx);
	if (changed) shm_free(changed);
error0:
	LOG(L_ERR, "ERROR: cfg_set_delayed(): failed to set the variable: %.*s.%.*s\n",
			group_name->len, group_name->s,
			var_name->len, var_name->s);

	convert_val_cleanup();
	return -1;
}
Example #5
0
/* wrapper function for cfg_set_now */
int cfg_set_now_str(cfg_ctx_t *ctx, str *group_name, str *var_name, str *val)
{
	return cfg_set_now(ctx, group_name, var_name, (void *)val, CFG_VAR_STR);
}
Example #6
0
/* wrapper function for cfg_set_now */
int cfg_set_now_int(cfg_ctx_t *ctx, str *group_name, str *var_name, int val)
{
	return cfg_set_now(ctx, group_name, var_name, (void *)(long)val, CFG_VAR_INT);
}