2 * Copyright (c) 2002, Stockholms universitet
3 * (Stockholm University, Stockholm Sweden)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the university nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
35 * Poller of fileserver
37 * Its part of the afs protocol that you need to talk the server now
38 * and then to make sure you don't have any droped callbacks.
40 * It is in its own module since mixing it with connection makes the
41 * connection code ever harder to read and understand the it is today,
42 * and there is enough of strange dependencies between clear conns and
43 * auth/crypto conns today and when they are allowed to be gc-ed, etc.
47 #include "arla_local.h"
52 #define POLLERCACHESIZE 101
54 #define POLLERHEAPSIZE 101
56 /* Hashtable of connections */
57 static Hashtab
*pollerhtab
;
63 int poller_timeout
= 300; /* 5 min */
64 int poller_downhost_timeout
= 60; /* 1 min */
66 static PROCESS poller_pid
;
68 enum { POLLER_RUNNING
, POLLER_SLEEPING
, POLLER_WAITING
} poller_status
;
71 * Functions for handling entries into the poller cache.
75 pollercmp (void *a
, void *b
)
77 PollerEntry
*c1
= (PollerEntry
*)a
;
78 PollerEntry
*c2
= (PollerEntry
*)b
;
80 return c1
->server
!= c2
->server
;
86 PollerEntry
*c
= (PollerEntry
*)a
;
92 poller_time_cmp (const void *a
, const void *b
)
94 PollerEntry
*c1
= (PollerEntry
*)a
;
95 PollerEntry
*c2
= (PollerEntry
*)b
;
97 return c1
->server
- c2
->server
;
102 * Add it to heap, use the minium of cell's timeout value and
103 * poller_{,downhost_}timeout.
107 poller_add(PollerEntry
*e
, int host_dead
, cell_entry
*c
)
112 timeout
= cell_get_poller_time(c
);
115 timeout
= max(poller_timeout
, poller_downhost_timeout
);
118 timeout
= min(poller_timeout
, timeout
);
120 timeout
= min(poller_downhost_timeout
, timeout
);
122 e
->timeout
= timeout
+ time(NULL
);
124 heap_insert(pollerheap
, e
, &e
->heapptr
);
126 switch(poller_status
) {
127 case POLLER_SLEEPING
:
128 /* we can only insert before first entry if its the short
129 * timeout, that is host_dead -> poller_downhost_timeout */
131 IOMGR_Cancel(poller_pid
);
134 LWP_NoYieldSignal(poller_add
);
145 * Add a poller event for this conn, there is really a fcache entry
146 * that will need to be refreshed.
150 poller_add_conn(ConnCacheEntry
*conn
)
155 key
.server
= rx_HostOf(rx_PeerOf(conn
->connection
));
157 cell
= cell_get_by_id(conn
->cell
);
159 e
= hashtabsearch(pollerhtab
, &key
);
161 e
= malloc(sizeof(*e
));
165 e
->server
= rx_HostOf(rx_PeerOf(conn
->connection
));
166 e
->cell
= conn
->cell
;
168 hashtabadd(pollerhtab
, e
);
170 heap_remove(pollerheap
, e
->heapptr
);
173 poller_add(e
, 0, cell
);
179 poller_remove(PollerEntry
*e
)
181 assert(e
->refcount
> 0);
184 if (e
->refcount
== 0) {
185 hashtabdel(pollerhtab
, e
);
186 heap_remove(pollerheap
, e
->heapptr
);
191 struct poller_intr_arg
{
192 poller_iter_func func
;
197 poller_foreach_func(void *ptr
, void *arg
)
199 PollerEntry
*e
= ptr
;
200 struct poller_intr_arg
*a
= arg
;
202 (*a
->func
)(e
->cell
, e
->server
, a
->arg
);
208 poller_foreach(poller_iter_func iter_func
, void *arg
)
210 struct poller_intr_arg a
;
214 hashtabforeach(pollerhtab
, poller_foreach_func
, &a
);
224 * Loop waiting for things servers to probe.
236 poller_status
= POLLER_RUNNING
;
238 arla_warnx(ADEBCONN
, "poller waiting");
242 e
= (PollerEntry
*)heap_head(pollerheap
);
244 poller_status
= POLLER_WAITING
;
245 LWP_WaitProcess(poller_add
);
247 } else if (e
->timeout
> now
) {
248 poller_status
= POLLER_SLEEPING
;
249 IOMGR_Sleep (e
->timeout
- now
);
253 arla_warnx(ADEBCONN
, "running poller");
257 /* XXX should a dead host break callbacks ? */
261 if (connected_mode
!= DISCONNECTED
) {
262 ConnCacheEntry
*conn
;
265 ce
= cred_get (e
->cell
, 0, CRED_NONE
);
268 conn
= conn_get (e
->cell
, e
->server
, afsport
,
269 FS_SERVICE_ID
, fs_probe
, ce
);
273 if (!conn_isalivep (conn
))
275 else if (fs_probe(conn
->connection
) != 0)
282 cell
= cell_get_by_id(e
->cell
);
286 heap_remove(pollerheap
, e
->heapptr
);
287 poller_add(e
, host_dead_p
, cell
);
289 arla_warnx(ADEBCONN
, "poller done");
294 * Find and return the cell for given `server', if the cell can't be
299 poller_host2cell(uint32_t server
)
305 e
= hashtabsearch(pollerhtab
, &key
);
312 * Initialize the poller.
318 arla_warnx (ADEBCONN
, "initpoller");
320 pollerhtab
= hashtabnew (POLLERCACHESIZE
, pollercmp
, pollerhash
);
321 if (pollerhtab
== NULL
)
322 arla_errx (1, ADEBERROR
, "poller_init: hashtabnew failed");
324 pollerheap
= heap_new(POLLERHEAPSIZE
, poller_time_cmp
);
325 if (pollerheap
== NULL
)
326 arla_errx (1, ADEBERROR
, "poller_init: heap_new failed");
328 poller_status
= POLLER_RUNNING
;
330 if (LWP_CreateProcess (poller
, 0, 1, NULL
, "poller", &poller_pid
))
331 arla_errx (1, ADEBERROR
,
332 "conn: cannot create poller thread");