Exemplo n.º 1
0
/*! Steal a block with available vma[s]. */
static struct block *
S_block_steal_and_lock(void)
{
  int ret;
  struct block * block;
  struct superblock * superblock;

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  if (NULL == (superblock=S_superblock_get_and_lock())) {
    /* Unlock S_gpool. */
    LOCK_LET(&(S_gpool.lock));

    return NULL;
  }
  /* superblock will be locked by superblock_get(). */

  /* Get head of superblock's block list. */
  block = superblock->head;

  /* Lock block. */
  LOCK_GET(&(block->lock), block->lctr);

  /* Remove block from front of superblock's block list. */
  superblock->head = block->next;
  if (NULL != block->next) {
    block->next->prev = block->prev;
  }

  /* Increment superblock's block count. */
  superblock->bctr++;

  if (NULL == superblock->head) {
    /* Remove superblock from front of S_gpool's superblock list. */
    S_gpool.head = superblock->next;
    if (NULL != superblock->next) {
      superblock->next->prev = superblock->prev;
    }

    assert(SUPERBLOCK_CTR_FULL == superblock->bctr);
  }

  /* Unlock superblock. */
  LOCK_LET(&(superblock->lock));

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));

  DBG_LOG(stderr, "stole block %p-%p\n", (void*)block,\
    (void*)((char*)block+BLOCK_SIZE));

  return block;
}
Exemplo n.º 2
0
/*! Free a superblock with no used blocks. */
static void
S_superblock_unlock_and_put(struct superblock * const superblock)
{
  int ret;

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  /* Remove superblock from S_gpool's superblock list. */
  if (S_gpool.head == superblock) {
    S_gpool.head = superblock->next;
  }
  else {
    superblock->prev->next = superblock->next;
  }
  if (NULL != superblock->next) {
    superblock->next->prev = superblock->prev;
  }

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));

  /* Unlock superblock. */
  LOCK_LET(&(superblock->lock));

  /* Free superblock's lock. */
  ret = lock_free(&(superblock->lock));
  assert(!ret);

  /* Destroy superblock's block list. */
  S_superblock_list_destroy(superblock);

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  /* Accumulate superblock's block wait counter. */
  S_gpool.blctr += superblock->blctr;
  /* Accumulate superblock's wait counter. */
  S_gpool.slctr += superblock->lctr;

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));

  /* Release back to system. */
  ret = CALL_SYS_FREE(superblock, SUPERBLOCK_SIZE);
  assert(SYS_FREE_FAIL != ret);

  DBG_LOG(stderr, "put superblock %p-%p\n", (void*)superblock,\
    (void*)((char*)superblock+SUPERBLOCK_SIZE));
}
Exemplo n.º 3
0
static int
bdb_cache_entry_db_lock( struct bdb_info *bdb, DB_TXN *txn, EntryInfo *ei,
	int rw, int tryOnly, DB_LOCK *lock )
{
#ifdef NO_DB_LOCK
	return 0;
#else
	int       rc;
	DBT       lockobj;
	int       db_rw;

	if ( !lock ) return 0;

	if (rw)
		db_rw = DB_LOCK_WRITE;
	else
		db_rw = DB_LOCK_READ;

	DBTzero( &lockobj );
	lockobj.data = &ei->bei_id;
	lockobj.size = sizeof(ei->bei_id) + 1;

	rc = LOCK_GET(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0,
					&lockobj, db_rw, lock);
	if (rc && !tryOnly) {
		Debug( LDAP_DEBUG_TRACE,
			"bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n",
			ei->bei_id, rw, rc );
	}
	return rc;
#endif /* NO_DB_LOCK */
}
Exemplo n.º 4
0
int
bdb_cache_entry_db_lock
( DB_ENV *env, u_int32_t locker, Entry *e, int rw, u_int32_t flags, DB_LOCK *lock )
{
#ifdef NO_THREADS
	return 0;
#else
	int       rc;
	DBT       lockobj;
	int       db_rw;

	if (rw)
		db_rw = DB_LOCK_WRITE;
	else
		db_rw = DB_LOCK_READ;

	lockobj.data = e->e_nname.bv_val;
	lockobj.size = e->e_nname.bv_len;
	rc = LOCK_GET(env, locker, flags | DB_LOCK_NOWAIT,
					&lockobj, db_rw, lock);
	if (rc) {
#ifdef NEW_LOGGING
		LDAP_LOG( CACHE, DETAIL1, 
			"bdb_cache_entry_db_lock: entry %s, rw %d, rc %d\n",
			e->e_nname.bv_val, rw, rc );
#else
		Debug( LDAP_DEBUG_TRACE,
			"bdb_cache_entry_db_lock: entry %s, rw %d, rc %d\n",
			e->e_nname.bv_val, rw, rc );
#endif
	}
	return rc;
#endif /* NO_THREADS */
}
Exemplo n.º 5
0
static void rpc_set_queue(rpc_t *rpc, void *c) {
	unsigned int queue_no = MAX_QUEUES, pipe_no = MAX_PIPES;
	str method, method_buf;


	if (rpc->scan(c, "dSd", &queue_no, &method, &pipe_no) < 3) return;

	if (pipe_no >= MAX_PIPES || (int)pipe_no < 0) {
		LM_ERR("Invalid pipe number: %d\n", pipe_no);
		rpc->fault(c, 400, "Invalid pipe number");
		return;
	}

	if (str_cpy(&method_buf, &method)) {
		LM_ERR("out of memory\n");
		rpc->fault(c, 400, "OOM");
		return;
	}

	LOCK_GET(rl_lock);
	if (queue_no >= *nqueues) {
		LM_ERR("MAX_QUEUES reached for queue: %d\n", queue_no);
		rpc->fault(c, 400, "MAX_QUEUES reached");
		LOCK_RELEASE(rl_lock);
		return;
	}

	*queues[queue_no].pipe = pipe_no;
	if (!queues[queue_no].method->s)
		shm_free(queues[queue_no].method->s);
	queues[queue_no].method->s = method_buf.s;
	queues[queue_no].method->len = method_buf.len;
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 6
0
static void rpc_set_pipe(rpc_t *rpc, void *c) {
	int pipe_no = MAX_PIPES, algo_id, limit = 0;
	str algo_str;

	if (rpc->scan(c, "dSd", &pipe_no, &algo_str, &limit) < 3) return;

	if (str_map_str(algo_names, &algo_str, &algo_id)) {
		LM_ERR("unknown algorithm: '%.*s'\n", algo_str.len, algo_str.s);
		rpc->fault(c, 400, "Unknown algorithm");
		return;
	}

	LM_DBG("set_pipe: %d:%d:%d\n", pipe_no, algo_id, limit);

	if (pipe_no >= MAX_PIPES || pipe_no < 0) {
		LM_ERR("wrong pipe_no: %d\n", pipe_no);
		rpc->fault(c, 400, "Unknown pipe");
		return;
	}

	LOCK_GET(rl_lock);
	*pipes[pipe_no].algo = algo_id;
	*pipes[pipe_no].limit = limit;

	if (check_feedback_setpoints(0)) {
		LM_ERR("feedback limits don't match\n");
		rpc->fault(c, 400, "Feedback limits don't match");
	} else {
		*pid_setpoint = 0.01 * (double)cfg_setpoint;
	}

	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 7
0
struct mi_root* mi_push_load(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	double value;
	char c[5];

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(c, node->value.s, node->value.len);
	c[node->value.len] = '\0';
	value = strtod(c, NULL);
	if (value < 0.0 || value > 1.0) {
		LM_ERR("value out of range: %0.3f in not in [0.0,1.0]\n", value);
		goto bad_syntax;
	}
	LOCK_GET(rl_lock);
	*load_value = value;
	LOCK_RELEASE(rl_lock);

	do_update_load();

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 8
0
struct mi_root* mi_set_dbg(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int dbg_mode = 0;

	node = cmd_tree->node.kids; 
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&dbg_mode)<0)
		goto bad_syntax;

	LOCK_GET(rl_lock);
	if (dbg_mode) {
		if (!rl_dbg_str->s) {
			rl_dbg_str->len = (MAX_PIPES * 5 * sizeof(char));
			rl_dbg_str->s = (char *)shm_malloc(rl_dbg_str->len);
			if (!rl_dbg_str->s) {
				rl_dbg_str->len = 0;
				LM_ERR("oom: %d\n", rl_dbg_str->len);
			}
		}
	} else {
		if (rl_dbg_str->s) {
			shm_free(rl_dbg_str->s);
			rl_dbg_str->s = NULL;
			rl_dbg_str->len = 0;
		}
	}
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 9
0
struct mi_root* mi_set_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	char i[5], p[5], d[5];

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(i, node->value.s, node->value.len);
	i[node->value.len] = '\0';

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(p, node->value.s, node->value.len);
	p[node->value.len] = '\0';

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(d, node->value.s, node->value.len);
	d[node->value.len] = '\0';

	LOCK_GET(rl_lock);
	*pid_ki = strtod(i, NULL);
	*pid_kp = strtod(p, NULL);
	*pid_kd = strtod(d, NULL);
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 10
0
struct mi_root* mi_get_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;
	node = add_mi_node_child(rpl, 0, "PID", 3, 0, 0);
	if(node == NULL)
		goto error;
	LOCK_GET(rl_lock);
	attr= addf_mi_attr(node, 0, "ki", 2, "%0.3f", *pid_ki);
	if(attr == NULL)
		goto error;
	attr= addf_mi_attr(node, 0, "kp", 2, "%0.3f", *pid_kp);
	if(attr == NULL)
		goto error;
	attr= addf_mi_attr(node, 0, "kd", 2, "%0.3f", *pid_kd);
	LOCK_RELEASE(rl_lock);
	if(attr == NULL)
		goto error;

	return rpl_tree;

error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree);
	return 0;
}
Exemplo n.º 11
0
/*! This will test the functionality of S_superblock_unlock_and_put() when
 *  superblock is the last superblock in S_gpool's superblock list. */
void superblock_4(void)
{
  int ret;
  void * retp;
  struct superblock * superblock1, * superblock2;

  /* ---- SETUP ---- */
  retp = CALL_SYS_ALLOC(superblock1, SUPERBLOCK_SIZE);
  assert(SYS_ALLOC_FAIL != retp);
  retp = CALL_SYS_ALLOC(superblock2, SUPERBLOCK_SIZE);
  assert(SYS_ALLOC_FAIL != retp);
  ret = lock_init(&(superblock1->lock));
  assert(!ret);
  ret = lock_init(&(superblock2->lock));
  assert(!ret);
  superblock1->prev = superblock2;
  superblock1->next = NULL;
  superblock2->prev = NULL;
  superblock2->next = superblock1;
  S_gpool.head = superblock2;
  LOCK_GET(&(superblock1->lock), null_ctr);

  /* ---- UNIT ---- */
  S_superblock_unlock_and_put(superblock1);

  /* ---- ASSERTIONS ---- */
  assert(superblock2 == S_gpool.head);
  assert(NULL == superblock2->prev);
  assert(NULL == superblock2->next);

  /* ---- CLEANUP ---- */
  ret = CALL_SYS_FREE(superblock2, SUPERBLOCK_SIZE);
  assert(SYS_FREE_FAIL != ret);
  S_gpool.head = NULL;
}
Exemplo n.º 12
0
static void rpc_set_pid(rpc_t *rpc, void *c) {
	double ki, kp, kd;

	if (rpc->scan(c, "fff", &ki, &kp, &kd) < 3) return;

	LOCK_GET(rl_lock);
	*pid_ki = ki;
	*pid_kp = kp;
	*pid_kd = kd;
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 13
0
/* rpc function implementations */
static void rpc_stats(rpc_t *rpc, void *c) {
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (rpc->printf(c, "PIPE[%d]: %d/%d (drop rate: %d)",
			i, *pipes[i].last_counter, *pipes[i].limit,
			*pipes[i].load) < 0) goto error;
	}
error:
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 14
0
struct mi_root* mi_get_pipes(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	str algo;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].algo), &len);
			if (str_map_int(algo_names, *pipes[i].algo, &algo))
				goto error;
			attr = add_mi_attr(node, 0, "algorithm", 9, algo.s, algo.len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].limit), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "limit", 5, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].counter), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len);
			if(attr == NULL)
				goto error;
		}
	}
	LOCK_RELEASE(rl_lock);
	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
Exemplo n.º 15
0
void
vma_gpool_gather(void)
{
  int ret;

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  /* Accumulate threads's S_mpool wait counter. */
  S_gpool.mlctr += S_mpool.lctr;

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));
}
Exemplo n.º 16
0
struct mi_root* mi_set_pipe(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int pipe_no = MAX_PIPES, algo_id, limit = 0;
	//str algo;

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0)
		goto bad_syntax;
	
	node = node->next;
	if ( !node->value.s || !node->value.len)
		goto bad_syntax;
	if (str_map_str(algo_names, &(node->value), (int*)&algo_id)) {
		LM_ERR("unknown algorithm: '%.*s'\n", node->value.len, node->value.s);
		goto bad_syntax;
	}

	node = node->next;
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&limit)<0)
		goto bad_syntax;

	LM_DBG("set pipe: %d:%d:%d\n", pipe_no, algo_id, limit);

	if (pipe_no >= MAX_PIPES) {
		LM_ERR("wrong pipe_no: %d\n", pipe_no);
		goto bad_syntax;
	}

	LOCK_GET(rl_lock);
	*pipes[pipe_no].algo = algo_id;
	*pipes[pipe_no].limit = limit;

	if (check_feedback_setpoints(0)) {
		LM_ERR("feedback limits don't match\n");
		goto error;
	} else {
		*pid_setpoint = 0.01 * (double)cfg_setpoint;
	}

	set_check_network_load();
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
error:
	LOCK_RELEASE(rl_lock);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 17
0
static void rpc_get_queues(rpc_t *rpc, void *c) {
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_QUEUES; i++) {
		if (queues[i].pipe) {
			if (rpc->printf(c, "QUEUE[%d]: %d:%.*s",
				i, *queues[i].pipe,
				(*queues[i].method).len,
				(*queues[i].method).s) < 0) goto error;
		}
	}
error:
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 18
0
struct mi_root* mi_set_queue(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	unsigned int queue_no = MAX_QUEUES, pipe_no = MAX_PIPES;
	str method;

	node = cmd_tree->node.kids;
	if (node == NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&queue_no)<0)
		goto bad_syntax;

	node = node->next;
	if ( !node->value.s || !node->value.len )
		goto bad_syntax;
	if (str_cpy(&method, &(node->value))) {
		LM_ERR("out of memory\n");
		goto early_error;
	}

	node = node->next;
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&pipe_no)<0)
		goto early_error;
	if (pipe_no >= MAX_PIPES) {
		LM_ERR("invalid pipe number: %d\n", pipe_no);
		goto early_error;
	}

	LOCK_GET(rl_lock);
	if (queue_no >= *nqueues) {
		LM_ERR("MAX_QUEUES reached for queue: %d\n", queue_no);
		goto error;
	}
	
	*queues[queue_no].pipe = pipe_no;
	if (!queues[queue_no].method->s)
		shm_free(queues[queue_no].method->s);
	queues[queue_no].method->s = method.s;
	queues[queue_no].method->len = method.len;
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
error:
	LOCK_RELEASE(rl_lock);
early_error:
	shm_free(method.s);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 19
0
/* mi function implementations */
struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			node = add_mi_node_child(rpl, 0, "PIPE", 4, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id", 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].load), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "load", 4, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*pipes[i].last_counter), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "counter", 7, p, len);
			if(attr == NULL)
				goto error;
		}
	}

	p = int2str((unsigned long)(*drop_rate), &len);
	node = add_mi_node_child(rpl, MI_DUP_VALUE, "DROP_RATE", 9, p, len);

	LOCK_RELEASE(rl_lock);
	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
Exemplo n.º 20
0
static void rpc_push_load(rpc_t *rpc, void *c) {
	double value;

	if (rpc->scan(c, "f", &value) < 1) return;

	if (value < 0.0 || value > 1.0) {
		LM_ERR("value out of range: %0.3f in not in [0.0,1.0]\n", value);
		rpc->fault(c, 400, "Value out of range");
		return;
	}
	LOCK_GET(rl_lock);
	*load_value = value;
	LOCK_RELEASE(rl_lock);

	do_update_load();
}
Exemplo n.º 21
0
struct mi_root* mi_get_queues(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr* attr;
	char* p;
	int i, len;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_QUEUES; i++) {
		if (queues[i].pipe) {
			node = add_mi_node_child(rpl, 0, "QUEUE", 5, 0, 0);
			if(node == NULL)
				goto error;

			p = int2str((unsigned long)(i), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "id" , 2, p, len);
			if(attr == NULL)
				goto error;

			p = int2str((unsigned long)(*queues[i].pipe), &len);
			attr = add_mi_attr(node, MI_DUP_VALUE, "pipe" , 4, p, len);
			if(attr == NULL)
				goto error;

			attr = add_mi_attr(node, 0, "method", 6,
				(*queues[i].method).s, (*queues[i].method).len);
			if(attr == NULL)
				goto error;
		}
	}
	LOCK_RELEASE(rl_lock);

	return rpl_tree;
error:
	LOCK_RELEASE(rl_lock);
	LM_ERR("Unable to create reply\n");
	free_mi_tree(rpl_tree); 
	return 0;
}
Exemplo n.º 22
0
static void rpc_get_pipes(rpc_t *rpc, void *c) {
	str algo;
	int i;

	LOCK_GET(rl_lock);
	for (i=0; i<MAX_PIPES; i++) {
		if (*pipes[i].algo != PIPE_ALGO_NOP) {
			if (str_map_int(algo_names, *pipes[i].algo, &algo))
				goto error;
			if (rpc->printf(c, "PIPE[%d]: %d:%.*s %d/%d (drop rate: %d) [%d]",
				i, *pipes[i].algo, algo.len, algo.s,
				*pipes[i].last_counter, *pipes[i].limit,
				*pipes[i].load, *pipes[i].counter) < 0) goto error;
		}
	}
error:
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 23
0
/* timer housekeeping, invoked each timer interval to reset counters */
static void rl_timer(unsigned int ticks, void *param)
{
	int i, len;
	char *c, *p;

	LOCK_GET(rl_lock);
	switch (*load_source) {
		case LOAD_SOURCE_CPU:
			update_cpu_load();
			break;
	}

	if (*check_network_load) {
		*network_load_value = get_total_bytes_waiting(PROTO_NONE);
	}

	if (rl_dbg_str->s) {
		c = p = rl_dbg_str->s;
		memset(c, ' ', rl_dbg_str->len);
		for (i=0; i<MAX_PIPES; i++) {
			c = int2str(*pipes[i].counter, &len);
			if (len < 4) {
				memcpy( p + (5-len), c, len );
			} else {
				memset(p, '*', 5);
				LM_WARN("Counter pipes[%d] to big: %d\n",
					i, *pipes[i].counter);
			}
			p = p + 5;
		}
		LM_WARN("%.*s\n", rl_dbg_str->len, rl_dbg_str->s);
	}

	for (i=0; i<MAX_PIPES; i++) {
		if( *pipes[i].algo == PIPE_ALGO_NETWORK ) {
			*pipes[i].load = ( *network_load_value > *pipes[i].limit ) ? 1 : -1;
		} else if (*pipes[i].limit && timer_interval) {
			*pipes[i].load = *pipes[i].counter / (*pipes[i].limit * timer_interval);
		}
		*pipes[i].last_counter = *pipes[i].counter;
		*pipes[i].counter = 0;
	}
	LOCK_RELEASE(rl_lock);
}
Exemplo n.º 24
0
/* timer housekeeping, invoked each timer interval to reset counters */
static ticks_t rl_timer_handle(ticks_t ticks, struct timer_ln* tl, void* data)
{
	int i, len;
	char *c, *p;

	LOCK_GET(rl_lock);
	switch (*load_source) {
		case LOAD_SOURCE_CPU:
			update_cpu_load();
			break;
	}

	*network_load_value = get_total_bytes_waiting();

	if (rl_dbg_str->s) {
		c = p = rl_dbg_str->s;
		memset(c, ' ', rl_dbg_str->len);
		for (i=0; i<MAX_PIPES; i++) {
			c = int2str(*pipes[i].counter, &len);
			if (len < 4) {
				memcpy( p + (5-len), c, len );
			} else {
				memset(p, '*', 5);
				LM_WARN("Counter pipes[%d] to big: %d\n",
					i, *pipes[i].counter);
			}
			p = p + 5;
		}
		LM_WARN("%.*s\n", rl_dbg_str->len, rl_dbg_str->s);
	}

	for (i=0; i<MAX_PIPES; i++) {
		if( *pipes[i].algo == PIPE_ALGO_NETWORK ) {
			*pipes[i].load = ( *network_load_value > *pipes[i].limit ) ? 1 : -1;
		} else if (*pipes[i].limit && timer_interval) {
			*pipes[i].load = *pipes[i].counter / (*pipes[i].limit * timer_interval);
		}
		*pipes[i].last_counter = *pipes[i].counter;
		*pipes[i].counter = 0;
	}
	LOCK_RELEASE(rl_lock);
	return (ticks_t)(-1); /* periodical */
}
Exemplo n.º 25
0
/*! Get a superblock with available block[s]. */
static struct superblock *
S_superblock_get_and_lock(void)
{
  int ret;
  void * retp;
  struct superblock * superblock;

  if (NULL == (superblock=S_gpool.head)) {
    /* Allocate new superblock. */
    retp = CALL_SYS_ALLOC(superblock, SUPERBLOCK_SIZE);
    if (SYS_ALLOC_FAIL == retp) {
      return NULL;
    }
    S_gpool.actr++;

    /* Prepend superblock to S_gpool's superblock list. */
    S_gpool.head = superblock;
    superblock->prev = NULL;
    superblock->next = NULL;

    /* Setup superblock. */
    superblock->bctr = 0;
    superblock->lctr = 0;
    superblock->blctr = 0;

    /* Initialize superblock's lock. */
    ret = lock_init(&(superblock->lock));
    assert(!ret);

    /* Setup superblock's block list. */
    S_superblock_list_setup(superblock);
  }

  /* Lock superblock. */
  LOCK_GET(&(superblock->lock), superblock->lctr);
  
  DBG_LOG(stderr, "got superblock %p-%p\n", (void*)superblock,\
    (void*)((char*)superblock+SUPERBLOCK_SIZE));

  return superblock;
}
Exemplo n.º 26
0
struct mi_root* mi_set_pid(struct mi_root* cmd_tree, void* param)
{
	struct mi_node *node;
	char buf[5];
	int rl_ki, rl_kp, rl_kd;

	if (!(node = cmd_tree->node.kids))
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;

	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_ki = strtod(buf, NULL);

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_kp = strtod(buf, NULL);

	node = node->next;
	if ( !node->value.s || !node->value.len || node->value.len >= 5)
		goto bad_syntax;
	memcpy(buf, node->value.s, node->value.len);
	buf[node->value.len] = '\0';
	rl_kd = strtod(buf, NULL);

	LOCK_GET(rl_lock);
	*pid_ki = rl_ki;
	*pid_kp = rl_kp;
	*pid_kd = rl_kd;
	LOCK_RELEASE(rl_lock);

	return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
bad_syntax:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
}
Exemplo n.º 27
0
/**
 * runs the current request through the queues
 * \param	forced_pipe	is >= 0 if a specific pipe should be used, < 0 otherwise
 * \return -1 if drop needed, 1 if allowed
 */
static int rl_check(struct sip_msg * msg, int forced_pipe)
{
	int que_id, pipe_id, ret;
	str method = msg->first_line.u.request.method;

	LOCK_GET(rl_lock);
	if (forced_pipe < 0) {
		if (find_queue(msg, &que_id)) {
			pipe_id = que_id = 0;
			ret = 1;
			goto out_release;
		}
		pipe_id = *queues[que_id].pipe;
	} else {
		que_id = 0; 
		pipe_id = forced_pipe;
	}

	ret = pipe_push(msg, pipe_id);
out_release:
	LOCK_RELEASE(rl_lock);

	/* no locks here because it's only read and pipes[pipe_id] is always alloc'ed */
	LOG(L_DBG,
			"meth=%.*s queue=%d pipe=%d algo=%d limit=%d pkg_load=%d counter=%d "
			"load=%2.1lf => %s\n",
			method.len,
			method.s, 
			que_id, 
			pipe_id,
			*pipes[pipe_id].algo,
			*pipes[pipe_id].limit,
			*pipes[pipe_id].load,
			*pipes[pipe_id].counter, 
			*load_value,
			(ret == 1) ? "ACCEPT" : "DROP");
	
	return ret;
}
Exemplo n.º 28
0
/**     
 * runs the current request through the queues
 * \param       forced_pipe     is >= 0 if a specific pipe should be used, < 0 otherwise
 * \return	-1 if drop needed, 1 if allowed
 */
static int rl_check(struct sip_msg * msg, int forced_pipe)
{
	int que_id, pipe_id, ret;
	str method = msg->first_line.u.request.method;

	if (forced_pipe >=0 && (forced_pipe>=MAX_PIPES || *pipes[forced_pipe].algo==PIPE_ALGO_NOP)) {
		LM_ERR("forced pipe %d out of range or not defined "
			" => defaulting to method type checking\n", forced_pipe);
		forced_pipe = -1;
	}

	LOCK_GET(rl_lock);
	if (forced_pipe < 0) { 
		if (find_queue(msg, &que_id)) {
			pipe_id = que_id = 0;
			ret = 1;
			goto out_release;
		}
		pipe_id = *queues[que_id].pipe;
	} else {
		que_id = 0;
		pipe_id = forced_pipe;
	}

	ret = pipe_push(msg, pipe_id);
out_release:
	LOCK_RELEASE(rl_lock);

	/* no locks here because it's only read and pipes[pipe_id] is always alloc'ed */
	LM_DBG("meth=%.*s queue=%d pipe=%d algo=%d limit=%d pkg_load=%d counter=%d "
		"load=%2.1lf network_load=%d => %s\n",
		method.len, method.s, que_id, pipe_id,
		*pipes[pipe_id].algo, *pipes[pipe_id].limit,
		*pipes[pipe_id].load, *pipes[pipe_id].counter,
		*load_value, *network_load_value, (ret == 1) ? "ACCEPT" : "DROP");

	return ret;
}
Exemplo n.º 29
0
static int
bdb_dn2id_lock( struct bdb_info *bdb, struct berval *dn,
	int rw, DB_TXN *txn, DB_LOCK *lock )
{
	int       rc;
	DBT       lockobj;
	int       db_rw;

	if (!txn)
		return 0;

	if (rw)
		db_rw = DB_LOCK_WRITE;
	else
		db_rw = DB_LOCK_READ;

	lockobj.data = dn->bv_val;
	lockobj.size = dn->bv_len;

	rc = LOCK_GET(bdb->bi_dbenv, TXN_ID(txn), DB_LOCK_NOWAIT,
					&lockobj, db_rw, lock);
	return rc;
}
Exemplo n.º 30
0
/* mi function implementations */
struct mi_root* mi_stats(struct mi_root* cmd_tree, void* param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node=NULL, *rpl=NULL;
	struct mi_attr *attr;
	int len;
	char * p;

	node = cmd_tree->node.kids;

	rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
	if (rpl_tree==0)
		return 0;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	if (rl_stats(rpl_tree, &node->value)) {
		LM_ERR("cannot mi print values\n");
		goto free;
	}

	if (!(node = add_mi_node_child(rpl, 0, "PIPE", 4, NULL, 0)))
		goto free;

	LOCK_GET(rl_lock);
	p = int2str((unsigned long)(*drop_rate), &len);
	if (!(attr = add_mi_attr(node, MI_DUP_VALUE, "drop_rate", 9, p, len))) {
		LOCK_RELEASE(rl_lock);
		goto free;
	}

	LOCK_RELEASE(rl_lock);
	return rpl_tree;
free:
	free_mi_tree(rpl_tree);
	return 0;
}