Пример #1
0
static void
disconnect_client (struct ropa_client *c)
{
    int ret;
    int i;

    assert (c->ref == 0);

    if (c->li) {
	listdel (lru_clients, c->li);
	c->li = NULL;
    }

    for (i = 0 ; i < c->numberOfInterfaces ; i++) {
	int ret = hashtabdel (ht_clients_ip, &c->addr[i]);
	assert (ret == 0);
	clear_addr (&c->addr[i]);
    }
    c->numberOfInterfaces = 0;
    c->port = 0;
    c->state = ROPAC_FREE;
    
    ret = hashtabdel (ht_clients_uuid, c);
    assert (ret == 0);
    c->li = listaddtail (lru_clients, c);
}
Пример #2
0
static void
create_clients (unsigned n)
{
    struct ropa_client *c;
    unsigned long i;

    c = calloc (n, sizeof (*c));
    if (c == NULL)
	err (1, "create_clients: calloc");

    for (i = 0 ; i < n; i++) {
#ifdef DIAGNOSTIC
	c[i].magic = DIAGNOSTIC_CLIENT;
	{
	    int j;
	    for (j = 0; j < sizeof(c->addr)/sizeof(c->addr[0]); j++)
		c[i].addr[j].magic = DIAGNOSTIC_ADDR;
	}
#endif
		 
	c[i].port = 0;
	c[i].lastseen = 0;
	c[i].callbacks = listnew();
	if (c[i].callbacks == NULL)
	    err (1, "create_clients: listnew");
	c[i].ref = 0;
	c[i].state = ROPAC_FREE;
	c[i].li = listaddtail (lru_clients, &c[i]);
    }
    num_clients += n;
}
Пример #3
0
static void
re_probe (ConnCacheEntry *e)
{
    Listitem *item;
    struct timeval tv;

    assert (e->probe != NULL);

    gettimeofday (&tv, NULL);
    if (e->probe_le) {
	listdel (connprobelist, e->probe_le);
	e->probe_next = min(tv.tv_sec + (1 << e->ntries), e->probe_next);
    } else
	e->probe_next = tv.tv_sec + (1 << e->ntries);

    if (e->ntries <= MAX_RETRIES)
	++e->ntries;

    for (item = listhead (connprobelist);
	 item;
	 item = listnext (connprobelist, item)) {
	ConnCacheEntry *this = (ConnCacheEntry *)listdata (item);

	if (e->probe_next < this->probe_next) {
	    e->probe_le = listaddbefore (connprobelist, item, e);
	    LWP_NoYieldSignal (connprobelist);
	    return;
	}
    }
    e->probe_le = listaddtail (connprobelist, e);
    LWP_NoYieldSignal (connprobelist);
}
Пример #4
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);
}
Пример #5
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;
}
Пример #6
0
static void
create_ccpairs (unsigned n) 
{
    struct ropa_ccpair *c;
    int i;

    c = malloc (n * sizeof (*c));
    if (c == NULL)
	err (1, "create_ccpairs: malloc");
    memset (c, 0, n * sizeof (*c));

    for (i = 0; i < n ; i++) {
#ifdef DIAGNOSTIC
	c[i].magic = DIAGNOSTIC_CCPAIR;
#endif
	c[i].li = listaddtail (lru_ccpair, &c[i]);
    }
    num_ccpair += n;
}
Пример #7
0
static void
break_ccpair (struct ropa_ccpair *cc, Bool notify_clientp)
{
    AFSCBFids fids;
    AFSCBs cbs;
    int ret;

    debug_print_callbacks();

    cc->expire = 0;

    if (cc->li)
	listdel (lru_ccpair, cc->li);

    if (notify_clientp) {
	fids.len = 1;
	fids.val = &cc->cb->fid;
	cbs.len = 0;
	notify_client (cc->client, &fids, &cbs);
    }

    if (cc->cb_li) {
	listdel (cc->cb->ccpairs, cc->cb_li);
	cc->cb_li = NULL;
    }

    /* The reverse of these are in add_client */
    ret = hashtabdel (ht_ccpairs, cc);
    assert (ret == 0);
    client_deref (cc->client);
    cc->client = NULL;
    callback_deref (cc->cb);
    cc->cb = NULL;

    heap_remove (heap_ccpairs, cc->heap);
    
    cc->li = listaddtail (lru_ccpair, cc);

    debug_print_callbacks();
}
Пример #8
0
static void
create_callbacks (unsigned n)
{
    struct ropa_cb *c;
    int i;

    c = malloc (n * sizeof (*c));
    if (c == NULL)
	err (1, "create_callbacks: malloc");
    memset (c, 0, n * sizeof (*c));

    for (i = 0; i < n ; i++) {
#ifdef DIAGNOSTIC
	c[i].magic = DIAGNOSTIC_CALLBACK;
#endif
	c[i].ccpairs = listnew();
	if (c[i].ccpairs == NULL)
	    err (1, "create_callbacks: listnew");
	c[i].li = listaddtail (lru_callback, &c[i]);
    }
    num_callbacks += n;
}
Пример #9
0
static void
register_vols_cb (void *data, int fd)
{
    struct dp_part *dp = (struct dp_part *)data;
    vstatus vs;
    int ret;
    volume_handle *vol;

    ret = vstatus_read (fd, &vs);
    if (ret)
	return;

    ret = vstatus2volume_handle (&vs, dp, &vol);
    if (ret) {
	mlog_log (MDEBERROR,
		  "register_vols_cb: failed to convert vstatus");
	return;
    }

    ret = VOLOP_OPEN(vol->type, dp, vol->vol, 
		     VOLOP_NOFLAGS, &vol->data);
    if (ret) {
	mlog_log (MDEBERROR,
		  "register_vols_cb: failed to open volume");
	vol->flags.attacherr = TRUE;
    } else {
	vol->flags.attacherr = FALSE;
    }
    vol->flags.offlinep = TRUE;
    vol->flags.salvaged = FALSE;
    vol->li = listaddtail (vol_list, vol);
    if (vol->li == NULL)
	errx (1, "register_vols_cb: listaddtail failed");

    hashtabadd (volume_htab, vol);
    
    return;
}
Пример #10
0
static void
callback_deref (struct ropa_cb *cb)
{
    cb->ref--;

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

    if (cb->ref == 0) {
	int ret = hashtabdel (ht_callbacks, cb);

	mlog_log (MDEBROPA, "cb_deref: removing %x.%x.%x",
		cb->fid.Volume, cb->fid.Vnode, cb->fid.Unique);

	assert (ret == 0);

	if (cb->li) 
	    listdel (lru_callback, cb->li);

	assert (listemptyp (cb->ccpairs));
	memset (&cb->fid, 0, sizeof(cb->fid));
	cb->li = listaddtail (lru_callback, cb);
    }
}
Пример #11
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;
}