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); }
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; }
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); }
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); }
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; }
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; }
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(); }
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; }
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; }
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); } }
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; }