Bug Summary

File:tubik/./../ubik/beacon.c
Location:line 425, column 6
Description:Value stored to 'code' is never read

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10#include <afsconfig.h>
11#include <afs/param.h>
12
13#include <roken.h>
14
15#include <lock.h>
16#include <rx/xdr.h>
17#include <rx/rx.h>
18#include <rx/rxkad.h>
19#include <rx/rx_multi.h>
20#include <afs/cellconfig.h>
21#ifndef AFS_NT40_ENV
22#include <afs/afsutil.h>
23#include <afs/netutils.h>
24#endif
25
26#define UBIK_INTERNALS
27#include "ubik.h"
28#include "ubik_int.h"
29
30/* These global variables were used to set the function to use to initialise
31 * the client security layer. They are retained for backwards compatiblity with
32 * legacy callers - the ubik_SetClientSecurityProcs() interface should be used
33 * instead
34 */
35int (*ubik_CRXSecurityProc) (void *rock, struct rx_securityClass **,
36 afs_int32 *);
37void *ubik_CRXSecurityRock;
38
39/*! \name statics used to determine if we're the sync site */
40static int nServers; /*!< total number of servers */
41static char amIMagic = 0; /*!< is this host the magic host */
42char amIClone = 0; /*!< is this a clone which doesn't vote */
43static char ubik_singleServer = 0;
44/*\}*/
45static int (*secLayerProc) (void *rock, struct rx_securityClass **,
46 afs_int32 *) = NULL((void *)0);
47static int (*tokenCheckProc) (void *rock) = NULL((void *)0);
48static void * securityRock = NULL((void *)0);
49
50afs_int32 ubikSecIndex;
51struct rx_securityClass *ubikSecClass;
52
53/* Values protected by the address lock */
54struct addr_data addr_globals;
55
56/* Values protected by the beacon lock */
57struct beacon_data beacon_globals;
58
59static int ubeacon_InitServerListCommon(afs_uint32 ame,
60 struct afsconf_cell *info,
61 char clones[],
62 afs_uint32 aservers[]);
63static int verifyInterfaceAddress(afs_uint32 *ame, struct afsconf_cell *info,
64 afs_uint32 aservers[]);
65
66/*! \file
67 * Module responsible for both deciding if we're currently the sync site,
68 * and keeping collecting votes so as to stay sync site.
69 *
70 * The basic module contacts all of the servers it can, trying to get them to vote
71 * for this server for sync site. The vote request message (called a beacon message)
72 * also specifies until which time this site claims to be the sync site, if at all, thus enabling
73 * receiving sites to know how long the sync site guarantee is made for.
74 *
75 * Each of these beacon messages is thus both a declaration of how long this site will
76 * remain sync site, and an attempt to extend that time by collecting votes for a later
77 * sync site extension.
78 *
79 * The voting module is responsible for choosing a reasonable time until which it promises
80 * not to vote for someone else. This parameter (BIG seconds) is not actually passed in
81 * the interface (perhaps it should be?) but is instead a compile time constant that both
82 * sides know about.
83
84 * The beacon and vote modules work intimately together; the vote module decides how long
85 * it should promise the beacon module its vote, and the beacon module takes all of these
86 * votes and decides for how long it is the synchronization site.
87 */
88
89/*! \brief procedure called from debug rpc call to get this module's state for debugging */
90void
91ubeacon_Debug(struct ubik_debug *aparm)
92{
93 /* fill in beacon's state fields in the ubik_debug structure */
94 aparm->syncSiteUntil = beacon_globals.syncSiteUntil;
95 aparm->nServers = nServers;
96}
97
98static int
99amSyncSite(void) {
100 afs_int32 now;
101 afs_int32 rcode;
102
103 /* special case for fast startup */
104 if (nServers == 1 && !amIClone)
105 return 1; /* one guy is always the sync site */
106
107 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 107), 0))
;
108 if (beacon_globals.ubik_amSyncSite == 0 || amIClone)
109 rcode = 0; /* if I don't think I'm the sync site, say so */
110 else {
111 now = FT_ApproxTime();
112 if (beacon_globals.syncSiteUntil <= now) { /* if my votes have expired, say so */
113 if (beacon_globals.ubik_amSyncSite)
114 ubik_dprint("Ubik: I am no longer the sync site\n");
115 beacon_globals.ubik_amSyncSite = 0;
116 rcode = 0;
117 } else {
118 rcode = 1; /* otherwise still have the required votes */
119 }
120 }
121 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 121), 0))
;
122 ubik_dprint("beacon: amSyncSite is %d\n", rcode);
123 return rcode;
124}
125
126/*!
127 * \brief Procedure that determines whether this site has enough current votes to remain sync site.
128 *
129 * Called from higher-level modules (everything but the vote module).
130 *
131 * If we're the sync site, check that our guarantees, obtained by the ubeacon_Interact()
132 * light-weight process, haven't expired. We're sync site as long as a majority of the
133 * servers in existence have promised us unexpired guarantees. The variable #ubik_syncSiteUntil
134 * contains the time at which the latest of the majority of the sync site guarantees expires
135 * (if the variable #ubik_amSyncSite is true)
136 * This module also calls up to the recovery module if it thinks that the recovery module
137 * may have to pick up a new database (which offucr sif [sic] we lose the sync site votes).
138 *
139 * \return 1 if local site is the sync site
140 * \return 0 if sync site is elsewhere
141 */
142int
143ubeacon_AmSyncSite(void)
144{
145 afs_int32 rcode;
146
147 rcode = amSyncSite();
148
149 if (!rcode)
150 urecovery_ResetState();
151
152 return rcode;
153}
154
155/*!
156 * \see ubeacon_InitServerListCommon()
157 */
158int
159ubeacon_InitServerListByInfo(afs_uint32 ame, struct afsconf_cell *info,
160 char clones[])
161{
162 afs_int32 code;
163
164 code = ubeacon_InitServerListCommon(ame, info, clones, 0);
165 return code;
166}
167
168/*!
169 * \param ame "address of me"
170 * \param aservers list of other servers
171 *
172 * \see ubeacon_InitServerListCommon()
173 */
174int
175ubeacon_InitServerList(afs_uint32 ame, afs_uint32 aservers[])
176{
177 afs_int32 code;
178
179 code =
180 ubeacon_InitServerListCommon(ame, (struct afsconf_cell *)0, 0,
181 aservers);
182 return code;
183}
184
185/* Must be called with address lock held */
186void
187ubeacon_InitSecurityClass(void)
188{
189 int i;
190 /* get the security index to use, if we can */
191 if (secLayerProc) {
192 i = (*secLayerProc) (securityRock, &addr_globals.ubikSecClass, &addr_globals.ubikSecIndex);
193 } else if (ubik_CRXSecurityProc) {
194 i = (*ubik_CRXSecurityProc) (ubik_CRXSecurityRock, &addr_globals.ubikSecClass,
195 &addr_globals.ubikSecIndex);
196 } else
197 i = 1;
198 if (i) {
199 /* don't have sec module yet */
200 addr_globals.ubikSecIndex = 0;
201 addr_globals.ubikSecClass = rxnull_NewClientSecurityObject();
202 }
203}
204
205void
206ubeacon_ReinitServer(struct ubik_server *ts)
207{
208 if (tokenCheckProc && !(*tokenCheckProc) (securityRock)) {
209 struct rx_connection *disk_rxcid;
210 struct rx_connection *vote_rxcid;
211 struct rx_connection *tmp;
212 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 212), 0))
;
213 ubeacon_InitSecurityClass();
214 disk_rxcid =
215 rx_NewConnection(rx_HostOf(rx_PeerOf(ts->disk_rxcid))((((ts->disk_rxcid)->peer))->host),
216 ubik_callPortal, DISK_SERVICE_ID51,
217 addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
218 if (disk_rxcid) {
219 tmp = ts->disk_rxcid;
220 ts->disk_rxcid = disk_rxcid;
221 rx_PutConnection(tmp)rx_DestroyConnection(tmp);
222 }
223 vote_rxcid =
224 rx_NewConnection(rx_HostOf(rx_PeerOf(ts->vote_rxcid))((((ts->vote_rxcid)->peer))->host),
225 ubik_callPortal, VOTE_SERVICE_ID50,
226 addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
227 if (vote_rxcid) {
228 tmp = ts->vote_rxcid;
229 ts->vote_rxcid = vote_rxcid;
230 rx_PutConnection(tmp)rx_DestroyConnection(tmp);
231 }
232 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 232), 0))
;
233 }
234}
235
236/*!
237 * \brief setup server list
238 *
239 * \param ame "address of me"
240 * \param aservers list of other servers
241 *
242 * called only at initialization to set up the list of servers to
243 * contact for votes. Just creates the server structure.
244 *
245 * The "magic" host is the one with the lowest internet address. It is
246 * magic because its vote counts epsilon more than the others. This acts
247 * as a tie-breaker when we have an even number of hosts in the system.
248 * For example, if the "magic" host is up in a 2 site system, then it
249 * is sync site. Without the magic host hack, if anyone crashed in a 2
250 * site system, we'd be out of business.
251 *
252 * \note There are two connections in every server structure, one for
253 * vote calls (which must always go through quickly) and one for database
254 * operations, which are subject to waiting for locks. If we used only
255 * one, the votes would sometimes get held up behind database operations,
256 * and the sync site guarantees would timeout even though the host would be
257 * up for communication.
258 *
259 * \see ubeacon_InitServerList(), ubeacon_InitServerListByInfo()
260 */
261int
262ubeacon_InitServerListCommon(afs_uint32 ame, struct afsconf_cell *info,
263 char clones[], afs_uint32 aservers[])
264{
265 struct ubik_server *ts;
266 afs_int32 me = -1;
267 afs_int32 servAddr;
268 afs_int32 i, code;
269 afs_int32 magicHost;
270 struct ubik_server *magicServer;
271
272 /* verify that the addresses passed in are correct */
273 if ((code = verifyInterfaceAddress(&ame, info, aservers)))
274 return code;
275
276 ubeacon_InitSecurityClass();
277
278 magicHost = ntohl(ame)(__builtin_constant_p(ame) ? ((((__uint32_t)(ame)) >> 24
) | ((((__uint32_t)(ame)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(ame)) & (0xff << 8)) << 8
) | (((__uint32_t)(ame)) << 24)) : __bswap32_var(ame))
; /* do comparisons in host order */
279 magicServer = (struct ubik_server *)0;
280
281 if (info) {
282 for (i = 0; i < info->numServers; i++) {
283 if (ntohl((afs_uint32) info->hostAddr[i].sin_addr.s_addr)(__builtin_constant_p((afs_uint32) info->hostAddr[i].sin_addr
.s_addr) ? ((((__uint32_t)((afs_uint32) info->hostAddr[i].
sin_addr.s_addr)) >> 24) | ((((__uint32_t)((afs_uint32)
info->hostAddr[i].sin_addr.s_addr)) & (0xff << 16
)) >> 8) | ((((__uint32_t)((afs_uint32) info->hostAddr
[i].sin_addr.s_addr)) & (0xff << 8)) << 8) | (
((__uint32_t)((afs_uint32) info->hostAddr[i].sin_addr.s_addr
)) << 24)) : __bswap32_var((afs_uint32) info->hostAddr
[i].sin_addr.s_addr))
==
284 ntohl((afs_uint32) ame)(__builtin_constant_p((afs_uint32) ame) ? ((((__uint32_t)((afs_uint32
) ame)) >> 24) | ((((__uint32_t)((afs_uint32) ame)) &
(0xff << 16)) >> 8) | ((((__uint32_t)((afs_uint32
) ame)) & (0xff << 8)) << 8) | (((__uint32_t)
((afs_uint32) ame)) << 24)) : __bswap32_var((afs_uint32
) ame))
) {
285 me = i;
286 if (clones[i]) {
287 amIClone = 1;
288 magicHost = 0;
289 }
290 }
291 }
292 nServers = 0;
293 for (i = 0; i < info->numServers; i++) {
294 if (i == me)
295 continue;
296 ts = (struct ubik_server *)malloc(sizeof(struct ubik_server));
297 memset(ts, 0, sizeof(struct ubik_server));
298 ts->next = ubik_servers;
299 ubik_servers = ts;
300 ts->addr[0] = info->hostAddr[i].sin_addr.s_addr;
301 if (clones[i]) {
302 ts->isClone = 1;
303 } else {
304 if (!magicHost
305 || ntohl((afs_uint32) ts->addr[0])(__builtin_constant_p((afs_uint32) ts->addr[0]) ? ((((__uint32_t
)((afs_uint32) ts->addr[0])) >> 24) | ((((__uint32_t
)((afs_uint32) ts->addr[0])) & (0xff << 16)) >>
8) | ((((__uint32_t)((afs_uint32) ts->addr[0])) & (0xff
<< 8)) << 8) | (((__uint32_t)((afs_uint32) ts->
addr[0])) << 24)) : __bswap32_var((afs_uint32) ts->addr
[0]))
<
306 (afs_uint32) magicHost) {
307 magicHost = ntohl(ts->addr[0])(__builtin_constant_p(ts->addr[0]) ? ((((__uint32_t)(ts->
addr[0])) >> 24) | ((((__uint32_t)(ts->addr[0])) &
(0xff << 16)) >> 8) | ((((__uint32_t)(ts->addr
[0])) & (0xff << 8)) << 8) | (((__uint32_t)(ts
->addr[0])) << 24)) : __bswap32_var(ts->addr[0]))
;
308 magicServer = ts;
309 }
310 ++nServers;
311 }
312 /* for vote reqs */
313 ts->vote_rxcid =
314 rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
315 ubik_callPortal, VOTE_SERVICE_ID50,
316 addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
317 /* for disk reqs */
318 ts->disk_rxcid =
319 rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
320 ubik_callPortal, DISK_SERVICE_ID51,
321 addr_globals.ubikSecClass, addr_globals.ubikSecIndex);
322 ts->up = 1;
323 }
324 } else {
325 i = 0;
326 while ((servAddr = *aservers++)) {
327 if (i >= MAXSERVERS20)
328 return UNHOSTS(5378L); /* too many hosts */
329 ts = (struct ubik_server *)malloc(sizeof(struct ubik_server));
330 memset(ts, 0, sizeof(struct ubik_server));
331 ts->next = ubik_servers;
332 ubik_servers = ts;
333 ts->addr[0] = servAddr; /* primary address in net byte order */
334 ts->vote_rxcid = rx_NewConnection(servAddr, ubik_callPortal, VOTE_SERVICE_ID50,
335 addr_globals.ubikSecClass, addr_globals.ubikSecIndex); /* for vote reqs */
336 ts->disk_rxcid = rx_NewConnection(servAddr, ubik_callPortal, DISK_SERVICE_ID51,
337 addr_globals.ubikSecClass, addr_globals.ubikSecIndex); /* for disk reqs */
338 ts->isClone = 0; /* don't know about clones */
339 ts->up = 1;
340 if (ntohl((afs_uint32) servAddr)(__builtin_constant_p((afs_uint32) servAddr) ? ((((__uint32_t
)((afs_uint32) servAddr)) >> 24) | ((((__uint32_t)((afs_uint32
) servAddr)) & (0xff << 16)) >> 8) | ((((__uint32_t
)((afs_uint32) servAddr)) & (0xff << 8)) << 8
) | (((__uint32_t)((afs_uint32) servAddr)) << 24)) : __bswap32_var
((afs_uint32) servAddr))
< (afs_uint32) magicHost) {
341 magicHost = ntohl(servAddr)(__builtin_constant_p(servAddr) ? ((((__uint32_t)(servAddr)) >>
24) | ((((__uint32_t)(servAddr)) & (0xff << 16)) >>
8) | ((((__uint32_t)(servAddr)) & (0xff << 8)) <<
8) | (((__uint32_t)(servAddr)) << 24)) : __bswap32_var
(servAddr))
;
342 magicServer = ts;
343 }
344 i++;
345 }
346 }
347 if (magicServer)
348 magicServer->magic = 1; /* remember for when counting votes */
349
350 if (!amIClone && !magicServer)
351 amIMagic = 1;
352 if (info) {
353 if (!amIClone)
354 ++nServers; /* count this server as well as the remotes */
355 } else
356 nServers = i + 1; /* count this server as well as the remotes */
357
358 ubik_quorum = (nServers >> 1) + 1; /* compute the majority figure */
359
360/* Shoud we set some defaults for RX??
361 r_retryInterval = 2;
362 r_nRetries = (RPCTIMEOUT/r_retryInterval);
363*/
364 if (info) {
365 if (!ubik_servers) /* special case 1 server */
366 ubik_singleServer = 1;
367 if (nServers == 1 && !amIClone) {
368 beacon_globals.ubik_amSyncSite = 1; /* let's start as sync site */
369 beacon_globals.syncSiteUntil = 0x7fffffff; /* and be it quite a while */
370 }
371 } else {
372 if (nServers == 1) /* special case 1 server */
373 ubik_singleServer = 1;
374 }
375
376 if (ubik_singleServer) {
377 if (!beacon_globals.ubik_amSyncSite)
378 ubik_dprint("Ubik: I am the sync site - 1 server\n");
379 beacon_globals.ubik_amSyncSite = 1;
380 beacon_globals.syncSiteUntil = 0x7fffffff; /* quite a while */
381 }
382 return 0;
383}
384
385/*!
386 * \brief main lwp loop for code that sends out beacons.
387 *
388 * This code only runs while we're sync site or we want to be the sync site.
389 * It runs in its very own light-weight process.
390 */
391void *
392ubeacon_Interact(void *dummy)
393{
394 afs_int32 code;
395 struct timeval tt;
396 struct rx_connection *connections[MAXSERVERS20];
397 struct ubik_server *servers[MAXSERVERS20];
398 afs_int32 i;
399 struct ubik_server *ts;
400 afs_int32 temp, yesVotes, lastWakeupTime, oldestYesVote, syncsite;
401 struct ubik_tid ttid;
402 struct ubik_version tversion;
403 afs_int32 startTime;
404
405 afs_pthread_setname_self("beacon");
406
407 /* loop forever getting votes */
408 lastWakeupTime = 0; /* keep track of time we last started a vote collection */
409 while (1) {
410
411 /* don't wakeup more than every POLLTIME seconds */
412 temp = (lastWakeupTime + POLLTIME15) - FT_ApproxTime();
413 /* don't sleep if last collection phase took too long (probably timed someone out ) */
414 if (temp > 0) {
415 if (temp > POLLTIME15)
416 temp = POLLTIME15;
417 tt.tv_sec = temp;
418 tt.tv_usec = 0;
419#ifdef AFS_PTHREAD_ENV1
420 code = select(0, 0, 0, 0, &tt);
421#else
422 code = IOMGR_Select(0, 0, 0, 0, &tt);
423#endif
424 } else
425 code = 0;
Value stored to 'code' is never read
426
427 lastWakeupTime = FT_ApproxTime(); /* started a new collection phase */
428
429 if (ubik_singleServer)
430 continue; /* special-case 1 server for speedy startup */
431
432 if (!uvote_ShouldIRun())
433 continue; /* if voter has heard from a better candidate than us, don't bother running */
434
435 /* otherwise we should run for election, or we're the sync site (and have already won);
436 * send out the beacon packets */
437 /* build list of all up hosts (noticing dead hosts are running again
438 * is a task for the recovery module, not the beacon module), and
439 * prepare to send them an r multi-call containing the beacon message */
440 i = 0; /* collect connections */
441 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 441), 0))
;
442 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 442), 0))
;
443 for (ts = ubik_servers; ts; ts = ts->next) {
444 if (ts->up && ts->addr[0] != ubik_host[0]) {
445 servers[i] = ts;
446 connections[i++] = ts->vote_rxcid;
447 }
448 }
449 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 449), 0))
;
450 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 450), 0))
;
451 servers[i] = (struct ubik_server *)0; /* end of list */
452 /* note that we assume in the vote module that we'll always get at least BIGTIME
453 * seconds of vote from anyone who votes for us, which means we can conservatively
454 * assume we'll be fine until SMALLTIME seconds after we start collecting votes */
455 /* this next is essentially an expansion of rgen's ServBeacon routine */
456
457 UBIK_VERSION_LOCK(void)((pthread_mutex_lock(&version_globals.version_lock)
== 0) || (osi_AssertFailU("pthread_mutex_lock(&version_globals.version_lock) == 0"
, "./../ubik/beacon.c", 457), 0))
;
458 ttid.epoch = version_globals.ubik_epochTime;
459 if (ubik_dbase->flags & DBWRITING1) {
460 /*
461 * if a write is in progress, we have to send the writeTidCounter
462 * which holds the tid counter of the write transaction , and not
463 * send the tidCounter value which holds the tid counter of the
464 * last transaction.
465 */
466 ttid.counter = ubik_dbase->writeTidCounter;
467 } else
468 ttid.counter = ubik_dbase->tidCounter + 1;
469 tversion.epoch = ubik_dbase->version.epoch;
470 tversion.counter = ubik_dbase->version.counter;
471 UBIK_VERSION_UNLOCK(void)((pthread_mutex_unlock(&version_globals.version_lock
) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&version_globals.version_lock) == 0"
, "./../ubik/beacon.c", 471), 0))
;
472
473 /* now analyze return codes, counting up our votes */
474 yesVotes = 0; /* count how many to ensure we have quorum */
475 oldestYesVote = 0x7fffffff; /* time quorum expires */
476 syncsite = amSyncSite();
477 if (!syncsite) {
478 /* Ok to use the DB lock here since we aren't sync site */
479 DBHOLD(ubik_dbase)(void)((pthread_mutex_lock(&((ubik_dbase)->versionLock
)) == 0) || (osi_AssertFailU("pthread_mutex_lock(&((ubik_dbase)->versionLock)) == 0"
, "./../ubik/beacon.c", 479), 0))
;
480 urecovery_ResetState();
481 DBRELE(ubik_dbase)(void)((pthread_mutex_unlock(&((ubik_dbase)->versionLock
)) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&((ubik_dbase)->versionLock)) == 0"
, "./../ubik/beacon.c", 481), 0))
;
482 }
483 startTime = FT_ApproxTime();
484 /*
485 * Don't waste time using mult Rx calls if there are no connections out there
486 */
487 if (i > 0) {
488 char hoststr[16];
489 multi_Rx(connections, i)do { struct multi_handle *multi_h; int multi_i; int multi_i0;
afs_int32 multi_error; struct rx_call *multi_call; multi_h =
multi_Init(connections, i); for (multi_i0 = multi_i = 0; ; multi_i
= multi_i0 )
{
490 multi_VOTE_Beacon(syncsite, startTime, &tversion,if (multi_h->nextReady == multi_h->firstNotReady &&
multi_i < multi_h->nConns) { multi_call = multi_h->
calls[multi_i]; if (multi_call) { StartVOTE_Beacon(multi_call
, syncsite, startTime, &tversion, &ttid); rx_FlushWrite
(multi_call); } multi_i0++; continue; } if ((multi_i = multi_Select
(multi_h)) < 0) break; multi_call = multi_h->calls[multi_i
]; multi_error = rx_EndCall(multi_call, EndVOTE_Beacon(multi_call
)); multi_h->calls[multi_i] = (struct rx_call *) 0
491 &ttid)if (multi_h->nextReady == multi_h->firstNotReady &&
multi_i < multi_h->nConns) { multi_call = multi_h->
calls[multi_i]; if (multi_call) { StartVOTE_Beacon(multi_call
, syncsite, startTime, &tversion, &ttid); rx_FlushWrite
(multi_call); } multi_i0++; continue; } if ((multi_i = multi_Select
(multi_h)) < 0) break; multi_call = multi_h->calls[multi_i
]; multi_error = rx_EndCall(multi_call, EndVOTE_Beacon(multi_call
)); multi_h->calls[multi_i] = (struct rx_call *) 0
;
492 temp = FT_ApproxTime(); /* now, more or less */
493 ts = servers[multi_i];
494 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 494), 0))
;
495 ts->lastBeaconSent = temp;
496 code = multi_error;
497 /* note that the vote time (the return code) represents the time
498 * the vote was computed, *not* the time the vote expires. We compute
499 * the latter down below if we got enough votes to go with */
500 if (code > 0) {
501 if ((code & ~0xff) == ERROR_TABLE_BASE_RXK(19270400L)) {
502 ubik_dprint("token error %d from host %s\n",
503 code, afs_inet_ntoa_r(ts->addr[0], hoststr));
504 ts->up = 0;
505 ts->beaconSinceDown = 0;
506 urecovery_LostServer(ts);
507 } else {
508 ts->lastVoteTime = code;
509 if (code < oldestYesVote)
510 oldestYesVote = code;
511 ts->lastVote = 1;
512 if (!ts->isClone)
513 yesVotes += 2;
514 if (ts->magic)
515 yesVotes++; /* the extra epsilon */
516 ts->up = 1; /* server is up (not really necessary: recovery does this for real) */
517 ts->beaconSinceDown = 1;
518 ubik_dprint("yes vote from host %s\n",
519 afs_inet_ntoa_r(ts->addr[0], hoststr));
520 }
521 } else if (code == 0) {
522 ts->lastVoteTime = temp;
523 ts->lastVote = 0;
524 ts->beaconSinceDown = 1;
525 ubik_dprint("no vote from %s\n",
526 afs_inet_ntoa_r(ts->addr[0], hoststr));
527 } else if (code < 0) {
528 ts->up = 0;
529 ts->beaconSinceDown = 0;
530 urecovery_LostServer(ts);
531 ubik_dprint("time out from %s\n",
532 afs_inet_ntoa_r(ts->addr[0], hoststr));
533 }
534 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 534), 0))
;
535 }
536 multi_Endmulti_Finalize(multi_h); } while (0);
537 }
538 /* now call our own voter module to see if we'll vote for ourself. Note that
539 * the same restrictions apply for our voting for ourself as for our voting
540 * for anyone else. */
541 i = SVOTE_Beacon((struct rx_call *)0, ubeacon_AmSyncSite(), startTime,
542 &tversion, &ttid);
543 if (i) {
544 yesVotes += 2;
545 if (amIMagic)
546 yesVotes++; /* extra epsilon */
547 if (i < oldestYesVote)
548 oldestYesVote = i;
549 }
550
551 /* now decide if we have enough votes to become sync site.
552 * Note that we can still get enough votes even if we didn't for ourself. */
553 if (yesVotes > nServers) { /* yesVotes is bumped by 2 or 3 for each site */
554 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 554), 0))
;
555 if (!beacon_globals.ubik_amSyncSite)
556 ubik_dprint("Ubik: I am the sync site\n");
557 beacon_globals.ubik_amSyncSite = 1;
558 beacon_globals.syncSiteUntil = oldestYesVote + SMALLTIME60;
559#ifndef AFS_PTHREAD_ENV1
560 /* I did not find a corresponding LWP_WaitProcess(&ubik_amSyncSite) --
561 this may be a spurious signal call -- sjenkins */
562 LWP_NoYieldSignal(&beacon_globals.ubik_amSyncSite);
563#endif
564 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 564), 0))
;
565 } else {
566 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 566), 0))
;
567 if (beacon_globals.ubik_amSyncSite)
568 ubik_dprint("Ubik: I am no longer the sync site\n");
569 beacon_globals.ubik_amSyncSite = 0;
570 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 570), 0))
;
571 DBHOLD(ubik_dbase)(void)((pthread_mutex_lock(&((ubik_dbase)->versionLock
)) == 0) || (osi_AssertFailU("pthread_mutex_lock(&((ubik_dbase)->versionLock)) == 0"
, "./../ubik/beacon.c", 571), 0))
;
572 urecovery_ResetState(); /* tell recovery we're no longer the sync site */
573 DBRELE(ubik_dbase)(void)((pthread_mutex_unlock(&((ubik_dbase)->versionLock
)) == 0) || (osi_AssertFailU("pthread_mutex_unlock(&((ubik_dbase)->versionLock)) == 0"
, "./../ubik/beacon.c", 573), 0))
;
574 }
575
576 } /* while loop */
577 return NULL((void *)0);
578}
579
580/*!
581 * \brief Verify that a given IP addresses does actually exist on this machine.
582 *
583 * \param ame the pointer to my IP address specified in the
584 * CellServDB file.
585 * \param aservers an array containing IP
586 * addresses of remote ubik servers. The array is
587 * terminated by a zero address.
588 *
589 * Algorithm : Verify that my IP addresses \p ame does actually exist
590 * on this machine. If any of my IP addresses are there
591 * in the remote server list \p aserver, remove them from
592 * this list. Update global variable \p ubik_host[] with
593 * my IP addresses.
594 *
595 * \return 0 on success, non-zero on failure
596 */
597static int
598verifyInterfaceAddress(afs_uint32 *ame, struct afsconf_cell *info,
599 afs_uint32 aservers[]) {
600 afs_uint32 myAddr[UBIK_MAX_INTERFACE_ADDR256], *servList, tmpAddr;
601 afs_uint32 myAddr2[UBIK_MAX_INTERFACE_ADDR256];
602 char hoststr[16];
603 int tcount, count, found, i, j, totalServers, start, end, usednetfiles =
604 0;
605
606 if (info)
607 totalServers = info->numServers;
608 else { /* count the number of servers */
609 for (totalServers = 0, servList = aservers; *servList; servList++)
610 totalServers++;
611 }
612
613 if (AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID) || AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID)) {
614 /*
615 * Find addresses we are supposed to register as per the netrestrict file
616 * if it exists, else just register all the addresses we find on this
617 * host as returned by rx_getAllAddr (in NBO)
618 */
619 char reason[1024];
620 count =
621 parseNetFiles(myAddr, NULL((void *)0), NULL((void *)0), UBIK_MAX_INTERFACE_ADDR256, reason,
622 AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID),
623 AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID));
624 if (count < 0) {
625 ubik_print("ubik: Can't register any valid addresses:%s\n",
626 reason);
627 ubik_print("Aborting..\n");
628 return UBADHOST(5385L);
629 }
630 usednetfiles++;
631 } else {
632 /* get all my interface addresses in net byte order */
633 count = rx_getAllAddr(myAddr, UBIK_MAX_INTERFACE_ADDR256);
634 }
635
636 if (count <= 0) { /* no address found */
637 ubik_print("ubik: No network addresses found, aborting..");
638 return UBADHOST(5385L);
639 }
640
641 /* verify that the My-address passed in by ubik is correct */
642 for (j = 0, found = 0; j < count; j++) {
643 if (*ame == myAddr[j]) { /* both in net byte order */
644 found = 1;
645 break;
646 }
647 }
648
649 if (!found) {
650 ubik_print("ubik: primary address %s does not exist\n",
651 afs_inet_ntoa_r(*ame, hoststr));
652 /* if we had the result of rx_getAllAddr already, avoid subverting
653 * the "is gethostbyname(gethostname()) us" check. If we're
654 * using NetInfo/NetRestrict, we assume they have enough clue
655 * to avoid that big hole in their foot from the loaded gun. */
656 if (usednetfiles) {
657 /* take the address we did get, then see if ame was masked */
658 *ame = myAddr[0];
659 tcount = rx_getAllAddr(myAddr2, UBIK_MAX_INTERFACE_ADDR256);
660 if (tcount <= 0) { /* no address found */
661 ubik_print("ubik: No network addresses found, aborting..");
662 return UBADHOST(5385L);
663 }
664
665 /* verify that the My-address passed in by ubik is correct */
666 for (j = 0, found = 0; j < tcount; j++) {
667 if (*ame == myAddr2[j]) { /* both in net byte order */
668 found = 1;
669 break;
670 }
671 }
672 }
673 if (!found)
674 return UBADHOST(5385L);
675 }
676
677 /* if any of my addresses are there in serverList, then
678 ** use that as my primary addresses : the higher level
679 ** application screwed up in dealing with multihomed concepts
680 */
681 for (j = 0, found = 0; j < count; j++) {
682 for (i = 0; i < totalServers; i++) {
683 if (info)
684 tmpAddr = (afs_uint32) info->hostAddr[i].sin_addr.s_addr;
685 else
686 tmpAddr = aservers[i];
687 if (myAddr[j] == tmpAddr) {
688 *ame = tmpAddr;
689 if (!info)
690 aservers[i] = 0;
691 found = 1;
692 }
693 }
694 }
695 if (found)
696 ubik_print("Using %s as my primary address\n", afs_inet_ntoa_r(*ame, hoststr));
697
698 if (!info) {
699 /* get rid of servers which were purged because all
700 ** those interface addresses are myself
701 */
702 for (start = 0, end = totalServers - 1; (start < end); start++, end--) {
703 /* find the first zero entry from the beginning */
704 for (; (start < end) && (aservers[start]); start++);
705
706 /* find the last non-zero entry from the end */
707 for (; (end >= 0) && (!aservers[end]); end--);
708
709 /* if there is nothing more to purge, exit from loop */
710 if (start >= end)
711 break;
712
713 /* move the entry */
714 aservers[start] = aservers[end];
715 aservers[end] = 0; /* this entry was moved */
716 }
717 }
718
719 /* update all my addresses in ubik_host in such a way
720 ** that ubik_host[0] has the primary address
721 */
722 ubik_host[0] = *ame;
723 for (j = 0, i = 1; j < count; j++)
724 if (*ame != myAddr[j])
725 ubik_host[i++] = myAddr[j];
726
727 return 0; /* return success */
728}
729
730
731/*!
732 * \brief Exchange IP address information with remote servers.
733 *
734 * \param ubik_host an array containing all my IP addresses.
735 *
736 * Algorithm : Do an RPC to all remote ubik servers informing them
737 * about my IP addresses. Get their IP addresses and
738 * update my linked list of ubik servers \p ubik_servers
739 *
740 * \return 0 on success, non-zero on failure
741 */
742int
743ubeacon_updateUbikNetworkAddress(afs_uint32 ubik_host[UBIK_MAX_INTERFACE_ADDR256])
744{
745 int j, count, code = 0;
746 UbikInterfaceAddr inAddr, outAddr;
747 struct rx_connection *conns[MAXSERVERS20];
748 struct ubik_server *ts, *server[MAXSERVERS20];
749 char buffer[32];
750 char hoststr[16];
751
752 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 752), 0))
;
753 for (count = 0, ts = ubik_servers; ts; count++, ts = ts->next) {
754 conns[count] = ts->disk_rxcid;
755 server[count] = ts;
756 }
757 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 757), 0))
;
758
759
760 /* inform all other servers only if there are more than one
761 * database servers in the cell */
762
763 if (count > 0) {
764
765 for (j = 0; j < UBIK_MAX_INTERFACE_ADDR256; j++)
766 inAddr.hostAddr[j] = ntohl(ubik_host[j])(__builtin_constant_p(ubik_host[j]) ? ((((__uint32_t)(ubik_host
[j])) >> 24) | ((((__uint32_t)(ubik_host[j])) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(ubik_host[j])) &
(0xff << 8)) << 8) | (((__uint32_t)(ubik_host[j]
)) << 24)) : __bswap32_var(ubik_host[j]))
;
767
768
769 /* do the multi-RX RPC to all other servers */
770 multi_Rx(conns, count)do { struct multi_handle *multi_h; int multi_i; int multi_i0;
afs_int32 multi_error; struct rx_call *multi_call; multi_h =
multi_Init(conns, count); for (multi_i0 = multi_i = 0; ; multi_i
= multi_i0 )
{
771 multi_DISK_UpdateInterfaceAddr(&inAddr, &outAddr)if (multi_h->nextReady == multi_h->firstNotReady &&
multi_i < multi_h->nConns) { multi_call = multi_h->
calls[multi_i]; if (multi_call) { StartDISK_UpdateInterfaceAddr
(multi_call, &inAddr); rx_FlushWrite(multi_call); } multi_i0
++; continue; } if ((multi_i = multi_Select(multi_h)) < 0)
break; multi_call = multi_h->calls[multi_i]; multi_error =
rx_EndCall(multi_call, EndDISK_UpdateInterfaceAddr(multi_call
, &outAddr)); multi_h->calls[multi_i] = (struct rx_call
*) 0
;
772 ts = server[multi_i]; /* reply received from this server */
773 if (!multi_error) {
774 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 774), 0))
;
775 if (ts->addr[0] != htonl(outAddr.hostAddr[0])(__builtin_constant_p(outAddr.hostAddr[0]) ? ((((__uint32_t)(
outAddr.hostAddr[0])) >> 24) | ((((__uint32_t)(outAddr.
hostAddr[0])) & (0xff << 16)) >> 8) | ((((__uint32_t
)(outAddr.hostAddr[0])) & (0xff << 8)) << 8) |
(((__uint32_t)(outAddr.hostAddr[0])) << 24)) : __bswap32_var
(outAddr.hostAddr[0]))
) {
776 code = UBADHOST(5385L);
777 strcpy(buffer, afs_inet_ntoa_r(ts->addr[0], hoststr));
778 ubik_print("ubik:Two primary addresses for same server \
779 %s %s\n", buffer,
780 afs_inet_ntoa_r(htonl(outAddr.hostAddr[0])(__builtin_constant_p(outAddr.hostAddr[0]) ? ((((__uint32_t)(
outAddr.hostAddr[0])) >> 24) | ((((__uint32_t)(outAddr.
hostAddr[0])) & (0xff << 16)) >> 8) | ((((__uint32_t
)(outAddr.hostAddr[0])) & (0xff << 8)) << 8) |
(((__uint32_t)(outAddr.hostAddr[0])) << 24)) : __bswap32_var
(outAddr.hostAddr[0]))
, hoststr));
781 } else {
782 for (j = 1; j < UBIK_MAX_INTERFACE_ADDR256; j++)
783 ts->addr[j] = htonl(outAddr.hostAddr[j])(__builtin_constant_p(outAddr.hostAddr[j]) ? ((((__uint32_t)(
outAddr.hostAddr[j])) >> 24) | ((((__uint32_t)(outAddr.
hostAddr[j])) & (0xff << 16)) >> 8) | ((((__uint32_t
)(outAddr.hostAddr[j])) & (0xff << 8)) << 8) |
(((__uint32_t)(outAddr.hostAddr[j])) << 24)) : __bswap32_var
(outAddr.hostAddr[j]))
;
784 }
785 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 785), 0))
;
786 } else if (multi_error == RXGEN_OPCODE-455) { /* pre 3.5 remote server */
787 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 787), 0))
;
788 ubik_print
789 ("ubik server %s does not support UpdateInterfaceAddr RPC\n",
790 afs_inet_ntoa_r(ts->addr[0], hoststr));
791 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 791), 0))
;
792 } else if (multi_error == UBADHOST(5385L)) {
793 code = UBADHOST(5385L); /* remote CellServDB inconsistency */
794 ubik_print("Inconsistent Cell Info on server: ");
795 UBIK_ADDR_LOCK(void)((pthread_mutex_lock(&addr_globals.addr_lock) == 0)
|| (osi_AssertFailU("pthread_mutex_lock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 795), 0))
;
796 for (j = 0; j < UBIK_MAX_INTERFACE_ADDR256 && ts->addr[j]; j++)
797 ubik_print("%s ", afs_inet_ntoa_r(ts->addr[j], hoststr));
798 UBIK_ADDR_UNLOCK(void)((pthread_mutex_unlock(&addr_globals.addr_lock) == 0
) || (osi_AssertFailU("pthread_mutex_unlock(&addr_globals.addr_lock) == 0"
, "./../ubik/beacon.c", 798), 0))
;
799 ubik_print("\n");
800 } else {
801 UBIK_BEACON_LOCK(void)((pthread_mutex_lock(&beacon_globals.beacon_lock) ==
0) || (osi_AssertFailU("pthread_mutex_lock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 801), 0))
;
802 ts->up = 0; /* mark the remote server as down */
803 UBIK_BEACON_UNLOCK(void)((pthread_mutex_unlock(&beacon_globals.beacon_lock)
== 0) || (osi_AssertFailU("pthread_mutex_unlock(&beacon_globals.beacon_lock) == 0"
, "./../ubik/beacon.c", 803), 0))
;
804 }
805 }
806 multi_Endmulti_Finalize(multi_h); } while (0);
807 }
808 return code;
809}
810
811void
812ubik_SetClientSecurityProcs(int (*secproc) (void *,
813 struct rx_securityClass **,
814 afs_int32 *),
815 int (*checkproc) (void *),
816 void *rock)
817{
818 secLayerProc = secproc;
819 tokenCheckProc = checkproc;
820 securityRock = rock;
821}