Example #1
0
static struct ropa_ccpair *
add_client (struct ropa_cb *cb, struct ropa_client *c)
{
    struct timeval tv;
    struct ropa_ccpair cckey, *cc;

    assert (cb && c);

    cckey.client = c;
    cckey.cb = cb;
    
    cc = hashtabsearch (ht_ccpairs, &cckey);

    if (cc) {
	listdel (lru_ccpair, cc->li);
	cc->li = listaddhead (lru_ccpair, cc);
	return cc;
    }

    /* The reverse of these are in break_ccpair */
    callback_ref (cb);
    client_ref (c);

    cc = listdeltail (lru_ccpair);
    DIAGNOSTIC_CHECK_CCPAIR(cc);    
    cc->li = NULL;

    if (ccpairs_inuse_p (cc))
	break_ccpair (cc, TRUE);

    /* XXX  do it for real */
    gettimeofday(&tv, NULL);
    cc->expire = tv.tv_sec + 3600;
    
    heap_insert (heap_ccpairs, cc, &cc->heap);
    LWP_NoYieldSignal (heap_ccpairs);
    cc->cb_li = listaddtail (cb->ccpairs, cc);
    
    cc->client = c;
    cc->cb = cb;
    cc->li = listaddhead (lru_ccpair, cc);
    hashtabadd (ht_ccpairs, cc);

    mlog_log (MDEBROPA, "add_client: added %x to callback %x.%x.%x",
	    c->addr[0].addr_in, cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique);

    return cc;
}
Example #2
0
static void
break_callback (struct ropa_cb *cb, struct ropa_client *caller, Bool break_own)
{
    struct ropa_ccpair *cc;
    struct ropa_ccpair *own_cc = NULL;

    assert (cb);
    assert (cb->ccpairs);

    mlog_log (MDEBROPA, "break_callback: breaking callback %x.%x.%x (%d)",
	    cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, break_own);

    callback_ref (cb);
    if (caller)
	client_ref (caller);

    while ((cc = listdelhead (cb->ccpairs)) != 0) {
	assert (cc->cb == cb);
	cc->cb_li = NULL;
	if (break_own)
	    break_ccpair (cc, cc->client != caller);
	else
	    if (cc->client == caller)
		own_cc = cc;
	    else
		break_ccpair (cc, TRUE);
    }

    if (own_cc)
	own_cc->cb_li = listaddhead (cb->ccpairs, own_cc);

    callback_deref (cb);
    if (caller)
	client_deref (caller);
}
Example #3
0
void
mnode_free (struct mnode *node, Bool bad)
{
    if (node->li)
	listdel (mnode_lru, node->li);
    /* 
       bad -> reread
       0 -> close
       */
    
    if (bad) {
	if (node->flags.fdp) 
	    close (node->fd);
	memset (&node->flags, 0, sizeof (node->flags));
    }
    if (--node->ref == 0) {
	if (node->flags.fdp) {
	    close (node->fd);
	    node->flags.fdp = FALSE;
	}

	if (node->flags.removedp == TRUE) {
	    hashtabdel (mnode_htab, node);
	    node->flags.removedp = FALSE;
	}
	mnode_numfree++;
	node->li = listaddtail (mnode_lru, node);
    } else
	node->li = listaddhead (mnode_lru, node);
}
Example #4
0
void
mnode_init (unsigned num)
{
    struct mnode *nodes = calloc (sizeof(struct mnode), num);
    int i;

    mnode_numfree = mnode_nodes = num;
    
    if (nodes == NULL)
	errx (1, "mnode_init: calloc failed");

    mnode_lru = listnew();
    if (mnode_lru == NULL)
	errx (1, "mnode_init: listnew returned NULL");
    
    for (i = 0; i < num ;i++) {
	nodes[i].li = listaddhead (mnode_lru, &nodes[i]);
	assert(nodes[i].li);
    }
    mnode_htab = hashtabnew (num * 2, /* XXX */
			     mnode_cmp,
			     mnode_hash);
    if (mnode_htab == NULL)
	errx (1, "mnode_init: hashtabnew returned NULL");
}
Example #5
0
static void
client_ref (struct ropa_client *c)
{
    assert (c->ref >= 0);
    if (c->li)
	listdel (lru_clients, c->li);
    c->ref++;
    if (c->li)
	c->li = listaddhead (lru_clients, c);
}
Example #6
0
int
mnode_find (const AFSFid *fid, struct mnode **node)
{
    struct mnode ptr, *res = NULL;
    
    ptr.fid = *fid;

    while (res == NULL) {
	res = hashtabsearch (mnode_htab, &ptr);
	
	if (res) {
	    if (res->flags.removedp == TRUE)
		return ENOENT;

	    if (res->li)
		listdel (mnode_lru, res->li);
	    if (res->ref == 0)
		mnode_numfree--;
	    res->ref++;
	} else if (mnode_numfree != 0) {
	    res = listdeltail (mnode_lru); assert (res);
	    assert (res->ref == 0);
	    hashtabdel (mnode_htab, res);
	    reset_node (res, fid);
	    hashtabadd (mnode_htab, res);
	    res->ref++;
	} else {
	    /* XXX */
	    mlog_log (MDEBWARN,
		      "mnode_find: no free nodes, had to malloc()");

	    res = malloc(sizeof(struct mnode));
	    if (res == NULL) {
		mlog_log (MDEBWARN,
			  "mnode_find: malloc() failed");
		LWP_DispatchProcess(); /* Yield */
		continue;
	    }

	    reset_node (res, fid);
	    hashtabadd (mnode_htab, res);
	    res->ref++;
	}
    }

    assert(res->flags.removedp == FALSE);

    *node = res;
    res->li = listaddhead (mnode_lru, *node);
    return 0;
}
Example #7
0
static void
callback_ref (struct ropa_cb *cb)
{
    assert (cb->ref >= 0);
    if (cb->li)
	listdel (lru_callback, cb->li);
    cb->ref++;

    mlog_log (MDEBROPA, "cb_ref: %x.%x.%x (%d)",
		cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, cb->ref);

    if (cb->li)
	cb->li = listaddhead (lru_callback, cb);
}
Example #8
0
static void
create_new_connections (unsigned n)
{
     unsigned i;
     ConnCacheEntry *entries;

     entries = (ConnCacheEntry*)calloc (n, sizeof (ConnCacheEntry));
     if (entries == NULL)
	 arla_errx (1, ADEBERROR, "conncache: calloc failed");
     for (i = 0; i < n; ++i) {
	  entries[i].connection = NULL;
	  entries[i].refcount   = 0;
	  entries[i].parent     = NULL;
	  entries[i].probe_le	= NULL;
	  listaddhead (connfreelist, &entries[i]);
     }
     nconnections += n;
}
Example #9
0
void
mnode_remove (const AFSFid *fid)
{
    struct mnode ptr, *res;
    
    ptr.fid = *fid;

    res = hashtabsearch (mnode_htab, &ptr);
    if (res) {
	if (res->ref == 0 && res->flags.fdp) {
	    close (res->fd);
	    res->flags.fdp = FALSE;
	}
	if (res->li)
	    listdel (mnode_lru, res->li);
	res->li = listaddhead (mnode_lru, res);
	res->flags.removedp = TRUE;
    }
}
Example #10
0
static void
recycle_conn (ConnCacheEntry *e)
{
    assert (e->refcount == 0);

    if (e->parent != NULL) {
	conn_free (e->parent);
	e->parent = NULL;
    }
    if (e->probe_le != NULL) {
	listdel (connprobelist, e->probe_le);
	e->probe_le = NULL;
    }
    if (!e->flags.killme)
	hashtabdel (connhtab, e);
    rx_DestroyConnection (e->connection);
    memset (e, 0, sizeof(*e));
    listaddhead (connfreelist, e);
    --nactive_connections;
}
Example #11
0
int
vld_init (void)
{
    struct dp_part *dp;
    int ret, partnum, i;
    

    db_lru = listnew();
    if (db_lru == NULL)
	errx (1, "vld_init: db_lru == NULL");

    for (i = 0; i < 100 /* XXX */ ; i++)
	listaddhead (db_lru, NULL);

    vol_list = listnew();
    if (vol_list == NULL)
	errx (1, "vld_init: vol_list == NULL");

    volume_htab = hashtabnew(volume_htab_sz, volume_cmp, volume_hash);
    if (volume_htab == NULL)
	errx (1, "vld_init: volume_htab == NULL");

    for (partnum = 0; partnum < 'z'-'a'; partnum++) {

	ret = dp_create (partnum , &dp);
	if (ret) {
	    warnx ("vld_init: dp_create(%d) returned %d", partnum, ret);
	    continue;
	}
	
	ret = dp_findvol (dp, register_vols_cb, dp);
	if (ret)
	    warnx ("vld_init: dp_findvol returned: %d", ret);

	dp_free (dp);
    }	
    return 0;
}
Example #12
0
int
ropa_getcallback (uint32_t host, uint16_t port, const struct AFSFid *fid,
		  AFSCallBack *callback, int32_t voltype)
{
    struct ropa_client *c;
    struct ropa_cb cbkey, *cb;
    struct ropa_ccpair *cc ;
    struct AFSFid callback_fid;

    debug_print_callbacks();

    c = client_query (host, port);
    if (c == NULL) {
	mlog_log (MDEBROPA, "ropa_getcallback: didn't find client %x/%d",
		  host, port);
	update_callback_time (DEFAULT_TIMEOUT, callback, CBSHARED);
	return 0;
    }

    /*
     * At this point the client should be firmly set
     * in the ropa client database.
     */

#if 0
    if (c->have_outstanding_callbacks)
	break_outstanding_callbacks (c);
#endif

    if (voltype == RWVOL) {
	callback_fid = *fid;
    } else {
	callback_fid.Volume = fid->Volume;
	callback_fid.Vnode = 0;
	callback_fid.Unique = 0;
    }

    cbkey.fid = callback_fid;

    cb = hashtabsearch (ht_callbacks, &cbkey);
    if (cb == NULL) {
	cb = listdeltail (lru_callback);
	DIAGNOSTIC_CHECK_CALLBACK(cb);
	cb->li = NULL;
	if (callback_inuse_p (cb)) {
	    break_callback (cb, NULL, FALSE);
	    callback_ref(cb);
	} else {
	    callback_ref(cb);
	    cb->li = listaddhead (lru_callback, cb);
	}
	cb->fid = callback_fid;
	hashtabadd (ht_callbacks, cb);

	mlog_log (MDEBROPA, "ropa_getcallback: added callback %x.%x.%x:%x",
		  callback_fid.Volume, callback_fid.Vnode,
		  callback_fid.Unique, host);
    } else {
	mlog_log (MDEBROPA, "ropa_getcallback: found callback %x.%x.%x:%x",
		  callback_fid.Volume, callback_fid.Vnode,
		  callback_fid.Unique, host);
	callback_ref(cb);
    }

    cc = add_client (cb, c);

    callback_deref (cb);

    update_callback (cc, callback, CBSHARED);

    debug_print_callbacks();

    return 0;
}
Example #13
0
static struct ropa_client *
client_query (uint32_t host, uint16_t port)
{
    struct ropa_client *c, *c_new;
    int ret;

    c = client_query_notalkback(host, port);
    if (c == NULL) {
	interfaceAddr remote;
	struct rx_connection *conn = NULL;

	c = obtain_client();
	assert (c->state == ROPAC_FREE && c->li == NULL);
	c->state = ROPAC_LOOKUP_U;
	c->flags |= ROPAF_LOOKUP;
	client_init (c, host, port, NULL, NULL);
	
	conn = rx_NewConnection (host, port, CM_SERVICE_ID,
				 rxnull_NewClientSecurityObject(),
				 0);
	if (conn == NULL) {
	    free(c);
	    return NULL;
	}
    retry:
	switch (c->state) {
	case ROPAC_DEAD:
	    c->li = listaddtail (lru_clients, c);
	    ret = ENETDOWN;
	    break;
	case ROPAC_LOOKUP_U:
	    ret = RXAFSCB_WhoAreYou (conn, &remote);
	    if (ret == RXGEN_OPCODE) {
		c->state = ROPAC_LOOKUP;
		goto retry;
	    } else if (ret == RX_CALL_DEAD) {
		c->state = ROPAC_DEAD;
		goto retry;
	    } else {
		struct ropa_client ckey;
		
		ckey.uuid = remote.uuid;
		c_new = hashtabsearch (ht_clients_uuid, &ckey);
		if (c_new == NULL) {
		    client_init (c, host, port, &remote.uuid, NULL);
		    ret = RXAFSCB_InitCallBackState3(conn, &server_uuid);
		} else {
		    client_update_interfaces (c_new, host, port, &remote);
		    disconnect_client (c);
		    c = c_new;
		    listdel(lru_clients, c->li);
		    c->li = NULL;
		}
	    }
	    break;
	case ROPAC_LOOKUP: {
	    afsUUID uuid;
	    ret = RXAFSCB_InitCallBackState(conn);
	    if (ret == RX_CALL_DEAD) {
		c->state = ROPAC_DEAD;
		goto retry;
	    }
	    uuid_init_simple (&uuid, host);
	    client_init (c, host, port, &uuid, NULL);
	    break;
	}
	default:
	     exit(-1);
	}
	
	rx_DestroyConnection (conn);
	
	if ((c->flags & ROPAF_WAITING) != 0)
	    LWP_NoYieldSignal (c);
	c->flags &= ~(ROPAF_LOOKUP|ROPAF_WAITING);

	if (ret) {
	    assert (c->li != NULL);
	    return NULL;
	}

	assert (c->li == NULL);
	c->li = listaddhead (lru_clients, c);

    } else { /* c != NULL */
	if ((c->flags & ROPAF_LOOKUP) != 0) {
	    c->flags |= ROPAF_WAITING;
	    LWP_WaitProcess (c);
	}
	assert (c->li != NULL);
    }

    return c;
}