Beispiel #1
0
static int
test_hash(void)
{
    Hashtab *h;

    starttesting("hashtab");

    h = hashtabnew(100, hash_cmp, hash_hash);
    if (!h)
	return endtesting(1);

    if (!hashtabadd(h, "one")||
	!hashtabadd(h, "two")||
	!hashtabadd(h, "three")||
	!hashtabadd(h, "four"))
	return endtesting(1);

    printf("foreach ----\n");
    hashtabforeach(h, hash_print, NULL);

    printf("search ----\none == %s\ntwo == %s\nthree == %s\nfour == %s\n", 
	   (char *)hashtabsearch(h, "one"),
	   (char *)hashtabsearch(h, "two"),
	   (char *)hashtabsearch(h, "three"),
	   (char *)hashtabsearch(h, "four"));

    hashtabrelease(h);

    return endtesting(0);
}
Beispiel #2
0
static ConnCacheEntry *
internal_get (int32_t cell,
	      uint32_t host,
	      uint16_t port,
	      uint16_t service,
	      int (*probe)(struct rx_connection *),
	      CredCacheEntry *ce)
{
    ConnCacheEntry *e;
    ConnCacheEntry key;

#if 0
    if (connected_mode == DISCONNECTED)
	return NULL;
#endif

    key.host          = host;
    key.port          = port;
    key.service       = service;
    key.cred          = ce->cred;
    key.securityindex = ce->securityindex;

    e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key);

    if (e == NULL) {
	ConnCacheEntry *parent = NULL;

	if (ce->securityindex || ce->cred) {
	    key.cred = 0;
	    key.securityindex = 0;
	    parent = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key);
	    if (parent == NULL) {
		parent = add_connection (cell, host, port, service,
					 probe, NULL);
	    }
	    ++parent->refcount;
	}

	e = add_connection (cell, host, port, service, probe, ce);
	if (parent != NULL)
	    e->parent = parent;
    }

    /*
     * Since we only probe the parent entry (ie noauth), we make sure
     * the status from the parent entry is pushed down to the
     * children.
     */
    if(e->parent != NULL) {
	e->flags.alivep = e->parent->flags.alivep;
    }

    return e;
}
Beispiel #3
0
static struct ropa_client *
uuid_query_simple (uint32_t host)
{
    struct ropa_client ckey;
    uuid_init_simple (&ckey.uuid, host);
    return hashtabsearch (ht_clients_uuid, &ckey);
}
Beispiel #4
0
int
ropa_drop_callbacks (uint32_t addr, uint16_t port,
		     const AFSCBFids *a_cbfids_p, const AFSCBs *a_cbs_p)
{
    struct ropa_client *c;
    struct ropa_cb cbkey, *cb;
    struct ropa_ccpair cckey, *cc;
    int i; 
    
    debug_print_callbacks();

    if (a_cbfids_p->len > AFSCBMAX)
	return EINVAL;

    c = client_query (addr, port);
    if (c == NULL) {
	mlog_log (MDEBROPA, "ropa_drop_callbacks: didn't find client %x/%d",
		  addr, port);
	return 0;
    }

    for (i = 0; i < a_cbfids_p->len; i++) {
	cbkey.fid = a_cbfids_p->val[i];
	
	cb = hashtabsearch (ht_callbacks, &cbkey);
	if (cb != NULL) {
	    cckey.client = c;
	    cckey.cb = cb;
	    
	    cc = hashtabsearch (ht_ccpairs, &cckey);
	    if (cc != NULL) {
		mlog_log (MDEBROPA, "ropa_drop: dropping %x.%x.%x:%x/%d",
			  cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique, 
			  addr, port);
		break_ccpair (cc, FALSE);
	    }
	}
    }
    
    debug_print_callbacks();

    return 0;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
static struct ropa_client *
client_query_notalkback (uint32_t host, uint16_t port)
{
    struct ropa_client ckey;
    struct ropa_addr *addr;
    ckey.numberOfInterfaces = 1;
    ckey.addr[0].c= &ckey;
    ckey.addr[0].addr_in = host;
    ckey.port = port;
    addr = hashtabsearch (ht_clients_ip, &ckey.addr[0]);
    if (addr) {
	assert (addr->c->numberOfInterfaces);
	return addr->c;
    }
    return NULL;
}
Beispiel #8
0
static int
break_fid (const struct AFSFid *fid, struct ropa_client *c,
	   Bool break_own)
{
    struct ropa_cb cbkey, *cb;

    cbkey.fid = *fid;
    
    cb = hashtabsearch (ht_callbacks, &cbkey);
    if (cb == NULL) {
	return -1;
    }

    break_callback (cb, c, break_own);

    return 0;
}
Beispiel #9
0
Symbol *
addsym(char *name)
{
    Symbol key, *s;

    key.name = name;
    s = (Symbol *) hashtabsearch(htab, (void *) &key);
    if (s == NULL) {
	s = (Symbol *) emalloc(sizeof(*s));
	s->name = name;
	s->gen_name = estrdup(name);
	output_name(s->gen_name);
	s->stype = SUndefined;
	hashtabadd(htab, s);
    }
    return s;
}
Beispiel #10
0
Bool
conn_serverupp (uint32_t host, uint16_t port, uint16_t service)
{
    ConnCacheEntry *e;
    ConnCacheEntry key;

    key.host          = host;
    key.port          = port;
    key.service       = service;
    key.cred          = 0;
    key.securityindex = 0;

    e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key);
    if (e != NULL)
	return e->flags.alivep;
    else
	return TRUE;
}
Beispiel #11
0
int32_t
conn_host2cell (uint32_t host, uint16_t port, uint16_t service)
{
    ConnCacheEntry *e;
    ConnCacheEntry key;

    key.host          = host;
    key.port          = port;
    key.service       = service;
    key.cred          = 0;
    key.securityindex = 0;

    e = (ConnCacheEntry *)hashtabsearch(connhtab, (void *)&key);
    if (e == NULL)
	return -1;
    else
	return e->cell;
}
Beispiel #12
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;
    }
}
Beispiel #13
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;
}
Beispiel #14
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;
}