Render the IP address for the "Ubik: Lost contact with sync-site" log
[openafs.git] / src / ubik / vote.c
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
14 #include <sys/types.h>
15 #ifdef AFS_NT40_ENV
16 #include <winsock2.h>
17 #else
18 #include <sys/file.h>
19 #include <netinet/in.h>
20 #endif
21 #include <lock.h>
22 #include <string.h>
23 #include <rx/xdr.h>
24 #include <rx/rx.h>
25 #include <afs/afsutil.h>
26 #include <time.h>
27 #include <stdarg.h>
28
29 #define UBIK_INTERNALS
30 #include "ubik.h"
31 #include "ubik_int.h"
32
33 /*! \file
34  * General Ubik Goal:
35  * The goal is to provide reliable operation among N servers, such that any
36  * server can crash with the remaining servers continuing operation within a
37  * short period of time.  While a \b short outage is acceptable, this time
38  * should be order of 3 minutes or less.
39  *
40  * Theory of operation:
41  *
42  * Note: #SMALLTIME and #BIGTIME are essentially the same time value, separated
43  * only by the clock skew, #MAXSKEW.  In general, if you are making guarantees
44  * for someone else, promise them no more than #SMALLTIME seconds of whatever
45  * invariant you provide.  If you are waiting to be sure some invariant is now
46  * \b false, wait at least #BIGTIME seconds to be sure that #SMALLTIME seconds
47  * has passed at the other site.
48  *
49  * Now, back to the design:
50  * One site in the collection is a special site, designated the \b sync site.
51  * The sync site sends periodic messages, which can be thought of as
52  * keep-alive messages.  When a non-sync site hears from the sync site, it
53  * knows that it is getting updates for the next #SMALLTIME seconds from that
54  * sync site.
55  *
56  * If a server does not hear from the sync site in #SMALLTIME seconds, it
57  * determines that it no longer is getting updates, and thus refuses to give
58  * out potentially out-of-date data.  If a sync site can not muster a majority
59  * of servers to agree that it is the sync site, then there is a possibility
60  * that a network partition has occurred, allowing another server to claim to
61  * be the sync site.  Thus, any time that the sync site has not heard from a
62  * majority of the servers in the last #SMALLTIME seconds, it voluntarily
63  * relinquishes its role as sync site.
64  * 
65  * While attempting to nominate a new sync site, certain rules apply.  First,
66  * a server can not reply "ok" (return 1 from ServBeacon) to two different
67  * hosts in less than #BIGTIME seconds; this allows a server that has heard
68  * affirmative replies from a majority of the servers to know that no other
69  * server in the network has heard enough affirmative replies in the last
70  * #BIGTIME seconds to become sync site, too.  The variables #ubik_lastYesTime
71  * and #lastYesHost are used by all servers to keep track of which host they
72  * have last replied affirmatively to, when queried by a potential new sync
73  * site.
74  *
75  * Once a sync site has become a sync site, it periodically sends beacon
76  * messages with a parameter of 1, indicating that it already has determined
77  * it is supposed to be the sync site.  The servers treat such a message as a
78  * guarantee that no other site will become sync site for the next #SMALLTIME
79  * seconds.  In the interim, these servers can answer a query concerning which
80  * site is the sync site without any communication with any server.  The
81  * variables #lastBeaconArrival and #lastBeaconHost are used by all servers to
82  * keep track of which sync site has last contacted them.
83  *
84  * One complication occurs while nominating a new sync site: each site may be
85  * trying to nominate a different site (based on the value of #lastYesHost),
86  * yet we must nominate the smallest host (under some order), to prevent this
87  * process from looping.  The process could loop by having each server give
88  * one vote to another server, but with no server getting a majority of the
89  * votes.  To avoid this, we try to withhold our votes for the server with the
90  * lowest internet address (an easy-to-generate order).  To this effect, we
91  * keep track (in #lowestTime and #lowestHost) of the lowest server trying to
92  * become a sync site.  We wait for this server unless there is already a sync
93  * site (indicated by ServBeacon's parameter being 1).
94  */
95
96 afs_int32 ubik_debugFlag = 0;   /*!< print out debugging messages? */
97
98 /*! \name these statics are used by all sites in nominating new sync sites */
99 afs_int32 ubik_lastYesTime = 0; /*!< time we sent the last \b yes vote */
100 static afs_uint32 lastYesHost = 0xffffffff;     /*!< host to which we sent \b yes vote */
101 /*\}*/
102 /*! \name Next is time sync site began this vote: guarantees sync site until this + SMALLTIME */
103 static afs_int32 lastYesClaim = 0;
104 static int lastYesState = 0;    /*!< did last site we voted for claim to be sync site? */
105 /*\}*/
106
107 /*! \name used to guarantee that nomination process doesn't loop */
108 static afs_int32 lowestTime = 0;
109 static afs_uint32 lowestHost = 0xffffffff;
110 static afs_int32 syncTime = 0;
111 static afs_int32 syncHost = 0;
112 /*\}*/
113
114 /*! \name used to remember which dbase version is the one at the sync site (for non-sync sites) */
115 struct ubik_version ubik_dbVersion;     /*!< sync site's dbase version */
116 struct ubik_tid ubik_dbTid;     /*!< sync site's tid, or 0 if none */
117 /*\}*/
118
119 /*!
120  * \brief Decide if we should try to become sync site.
121  *
122  * The basic rule is that we
123  * don't run if there is a valid sync site and it ain't us (we have to run if
124  * it is us, in order to keep our votes).  If there is no sync site, then we
125  * want to run if we're the lowest numbered host running, otherwise we defer to
126  * the lowest host.  However, if the lowest host hasn't been heard from for a
127  * while, then we start running again, in case he crashed.
128  *
129  * \return true if we should run, and false otherwise.
130  */
131 int
132 uvote_ShouldIRun(void)
133 {
134     register afs_int32 now;
135
136     now = FT_ApproxTime();
137     if (BIGTIME + ubik_lastYesTime < now)
138         return 1;               /* no valid guy even trying */
139     if (lastYesState && lastYesHost != ubik_host[0])
140         return 0;               /* other guy is sync site, leave him alone */
141     if (ntohl((afs_uint32) lastYesHost) < ntohl((afs_uint32) ubik_host[0]))
142         return 0;               /* if someone is valid and better than us, don't run */
143     /* otherwise we should run */
144     return 1;
145 }
146
147 /*!
148  * \brief Return the current synchronization site, if any.
149  *
150  * Simple approach: if the
151  * last guy we voted yes for claims to be the sync site, then we we're happy to
152  * use that guy for a sync site until the time his mandate expires.  If the guy
153  * does not claim to be sync site, then, of course, there's none.
154  *
155  * In addition, if we lost the sync, we set #urecovery_syncSite to an invalid
156  * value, indicating that we no longer know which version of the dbase is the
157  * one we should have.  We'll get a new one when we next hear from the sync
158  * site.
159  *
160  * \return 0 or currently valid sync site.  It can return our own
161  * address, if we're the sync site.
162  */
163 afs_int32
164 uvote_GetSyncSite(void)
165 {
166     register afs_int32 now;
167     register afs_int32 code;
168
169     if (!lastYesState)
170         code = 0;
171     else {
172         now = FT_ApproxTime();
173         if (SMALLTIME + lastYesClaim < now)
174             code = 0;           /* last guy timed out */
175         else
176             code = lastYesHost;
177     }
178     return code;
179 }
180
181 /*!
182  * \brief called by the sync site to handle vote beacons; if aconn is null, this is a
183  * local call
184  *
185  * \returns 0 or time when the vote was sent.  It returns 0 if we are
186  * not voting for this sync site, or the time we actually voted yes, if
187  * non-zero.
188  */
189 afs_int32
190 SVOTE_Beacon(register struct rx_call * rxcall, afs_int32 astate,
191              afs_int32 astart, struct ubik_version * avers,
192              struct ubik_tid * atid)
193 {
194     register afs_int32 otherHost;
195     register afs_int32 now;
196     afs_int32 vote;
197     struct rx_connection *aconn;
198     struct rx_peer *rxp;
199     struct ubik_server *ts;
200     int isClone = 0;
201
202     now = FT_ApproxTime();      /* close to current time */
203     if (rxcall) {               /* caller's host */
204         aconn = rx_ConnectionOf(rxcall);
205         rxp = rx_PeerOf(aconn);
206         otherHost = rx_HostOf(rxp);
207
208         /* get the primary interface address for this host.  */
209         /* This is the identifier that ubik uses. */
210         otherHost = ubikGetPrimaryInterfaceAddr(otherHost);
211         if (!otherHost) {
212             ubik_dprint("Received beacon from unknown host %s\n",
213                         afs_inet_ntoa(rx_HostOf(rxp)));
214             return 0;           /* I don't know about you: vote no */
215         }
216         for (ts = ubik_servers; ts; ts = ts->next) {
217             if (ts->addr[0] == otherHost)
218                 break;
219         }
220         if (!ts)
221             ubik_dprint("Unknown host %x has sent a beacon\n", otherHost);
222         if (ts && ts->isClone)
223             isClone = 1;
224     } else {
225         otherHost = ubik_host[0];       /* this host */
226         isClone = amIClone;
227     }
228
229     ubik_dprint("Received beacon type %d from host %s\n", astate,
230                 afs_inet_ntoa(otherHost));
231
232     /* compute the lowest server we've heard from.  We'll try to only vote for
233      * this dude if we don't already have a synchronization site.  Also, don't
234      * let a very old lowestHost confusing things forever.  We pick a new
235      * lowestHost after BIGTIME seconds to limit the damage if this host
236      * actually crashes.  Finally, we also count in this computation: don't
237      * pick someone else if we're even better!
238      * 
239      * Note that the test below must be <=, not <, so that we keep refreshing
240      * lowestTime.  Otherwise it will look like we haven't heard from
241      * lowestHost in a while and another host could slip in.  */
242
243
244     /* First compute the lowest host we've heard from, whether we want them
245      * for a sync site or not.  If we haven't heard from a site in BIGTIME
246      * seconds, we ignore its presence in lowestHost: it may have crashed.
247      * Note that we don't ever let anyone appear in our lowestHost if we're
248      * lower than them, 'cause we know we're up. */
249     /* But do not consider clones for lowesHost since they never may become
250      * sync site */
251     if (!isClone
252         && (ntohl((afs_uint32) otherHost) <= ntohl((afs_uint32) lowestHost)
253             || lowestTime + BIGTIME < now)) {
254         lowestTime = now;
255         lowestHost = otherHost;
256     }
257     /* why do we need this next check?  Consider the case where each of two
258      * servers decides the other is lowestHost.  Each stops sending beacons
259      * 'cause the other is there.  Not obvious that this process terminates:
260      * i.e. each guy could restart procedure and again think other side is
261      * lowest.  Need to prove: if one guy in the system is lowest and knows
262      * he's lowest, these loops don't occur.  because if someone knows he's
263      * lowest, he will send out beacons telling others to vote for him. */
264     if (!amIClone
265         && (ntohl((afs_uint32) ubik_host[0]) <= ntohl((afs_uint32) lowestHost)
266             || lowestTime + BIGTIME < now)) {
267         lowestTime = now;
268         lowestHost = ubik_host[0];
269     }
270
271     /* tell if we've heard from a sync site recently (even if we're not voting
272      * for this dude yet).  After a while, time the guy out. */
273     if (astate) {               /* this guy is a sync site */
274         syncHost = otherHost;
275         syncTime = now;
276     } else if (syncTime + BIGTIME < now) {
277         if (syncHost) {
278             ubik_dprint
279                 ("Ubik: Lost contact with sync-site %s (NOT in quorum)\n",
280                  afs_inet_ntoa(syncHost));
281         }
282         syncHost = 0;
283     }
284
285     /* decide how to vote */
286     vote = 0;                   /* start off voting no */
287
288     /* if we this guy isn't a sync site, we don't really have to vote for him.
289      * We get to apply some heuristics to try to avoid weird oscillation sates
290      * in the voting procedure. */
291     if (astate == 0) {
292         /* in here only if this guy doesn't claim to be a sync site */
293
294         /* lowestHost is also trying for our votes, then just say no. */
295         if (ntohl(lowestHost) != ntohl(otherHost)) {
296             return 0;
297         }
298
299         /* someone else *is* a sync site, just say no */
300         if (syncHost && syncHost != otherHost)
301             return 0;
302     } else /* fast startup if this is the only non-clone */ if (lastYesHost ==
303                                                                 0xffffffff
304                                                                 && otherHost
305                                                                 ==
306                                                                 ubik_host[0])
307     {
308         int i = 0;
309         for (ts = ubik_servers; ts; ts = ts->next) {
310             if (ts->addr[0] == otherHost)
311                 continue;
312             if (!ts->isClone)
313                 i++;
314         }
315         if (!i)
316             lastYesHost = otherHost;
317     }
318
319
320     if (isClone)
321         return 0;               /* clone never can become sync site */
322
323     /* Don't promise sync site support to more than one host every BIGTIME
324      * seconds.  This is the heart of our invariants in this system. */
325     if (ubik_lastYesTime + BIGTIME < now || otherHost == lastYesHost) {
326         if ((ubik_lastYesTime + BIGTIME < now) || (otherHost != lastYesHost)
327             || (lastYesState != astate)) {
328             /* A new vote or a change in the vote or changed quorum */
329             ubik_dprint("Ubik: vote 'yes' for %s %s\n",
330                         afs_inet_ntoa(otherHost),
331                         (astate ? "(in quorum)" : "(NOT in quorum)"));
332         }
333
334         vote = now;             /* vote yes */
335         ubik_lastYesTime = now; /* remember when we voted yes */
336         lastYesClaim = astart;  /* remember for computing when sync site expires */
337         lastYesHost = otherHost;        /* and who for */
338         lastYesState = astate;  /* remember if site is a sync site */
339         ubik_dbVersion = *avers;        /* resync value */
340         ubik_dbTid = *atid;     /* transaction id, if any, of active trans */
341         urecovery_CheckTid(atid);       /* check if current write trans needs aborted */
342     }
343     return vote;
344 }
345
346 /*!
347  * \brief Handle per-server debug command, where 0 is the first server.
348  *
349  * Basic network debugging hooks.
350  */
351 afs_int32
352 SVOTE_SDebug(struct rx_call * rxcall, afs_int32 awhich,
353              register struct ubik_sdebug * aparm)
354 {
355     afs_int32 code, isClone;
356     code = SVOTE_XSDebug(rxcall, awhich, aparm, &isClone);
357     return code;
358 }
359
360 afs_int32
361 SVOTE_XSDebug(struct rx_call * rxcall, afs_int32 awhich,
362               register struct ubik_sdebug * aparm, afs_int32 * isclone)
363 {
364     register struct ubik_server *ts;
365     register int i;
366     for (ts = ubik_servers; ts; ts = ts->next) {
367         if (awhich-- == 0) {
368             /* we're done */
369             aparm->addr = ntohl(ts->addr[0]);   /* primary interface */
370             for (i = 0; i < UBIK_MAX_INTERFACE_ADDR - 1; i++)
371                 aparm->altAddr[i] = ntohl(ts->addr[i + 1]);
372             aparm->lastVoteTime = ts->lastVoteTime;
373             aparm->lastBeaconSent = ts->lastBeaconSent;
374             memcpy(&aparm->remoteVersion, &ts->version,
375                    sizeof(struct ubik_version));
376             aparm->lastVote = ts->lastVote;
377             aparm->up = ts->up;
378             aparm->beaconSinceDown = ts->beaconSinceDown;
379             aparm->currentDB = ts->currentDB;
380             *isclone = ts->isClone;
381             return 0;
382         }
383     }
384     return 2;
385 }
386
387 afs_int32
388 SVOTE_XDebug(struct rx_call * rxcall, register struct ubik_debug * aparm,
389              afs_int32 * isclone)
390 {
391     afs_int32 code;
392
393     code = SVOTE_Debug(rxcall, aparm);
394     *isclone = amIClone;
395     return code;
396 }
397
398 /*!
399  * \brief Handle basic network debug command.  This is the global state dumper.
400  */
401 afs_int32
402 SVOTE_Debug(struct rx_call * rxcall, register struct ubik_debug * aparm)
403 {
404     int i;
405     /* fill in the basic debug structure.  Note the the RPC protocol transfers,
406      * integers in host order. */
407
408     aparm->now = FT_ApproxTime();
409     aparm->lastYesTime = ubik_lastYesTime;
410     aparm->lastYesHost = ntohl(lastYesHost);
411     aparm->lastYesState = lastYesState;
412     aparm->lastYesClaim = lastYesClaim;
413     aparm->lowestHost = ntohl(lowestHost);
414     aparm->lowestTime = lowestTime;
415     aparm->syncHost = ntohl(syncHost);
416     aparm->syncTime = syncTime;
417
418     /* fill in all interface addresses of myself in hostbyte order */
419     for (i = 0; i < UBIK_MAX_INTERFACE_ADDR; i++)
420         aparm->interfaceAddr[i] = ntohl(ubik_host[i]);
421
422     aparm->amSyncSite = ubik_amSyncSite;
423     ubeacon_Debug(aparm);
424
425     udisk_Debug(aparm);
426
427     ulock_Debug(aparm);
428
429     /* Get the recovery state. The label of the database may not have 
430      * been written yet but set the flag so udebug behavior remains.
431      * Defect 9477.
432      */
433     aparm->recoveryState = urecovery_state;
434     if ((urecovery_state & UBIK_RECSYNCSITE)
435         && (urecovery_state & UBIK_RECFOUNDDB)
436         && (urecovery_state & UBIK_RECHAVEDB)) {
437         aparm->recoveryState |= UBIK_RECLABELDB;
438     }
439     memcpy(&aparm->syncVersion, &ubik_dbVersion, sizeof(struct ubik_version));
440     memcpy(&aparm->syncTid, &ubik_dbTid, sizeof(struct ubik_tid));
441     aparm->activeWrite = (ubik_dbase->flags & DBWRITING);
442     aparm->tidCounter = ubik_dbase->tidCounter;
443
444     if (ubik_currentTrans) {
445         aparm->currentTrans = 1;
446         if (ubik_currentTrans->type == UBIK_WRITETRANS)
447             aparm->writeTrans = 1;
448         else
449             aparm->writeTrans = 0;
450     } else {
451         aparm->currentTrans = 0;
452     }
453
454     aparm->epochTime = ubik_epochTime;
455
456     return 0;
457 }
458
459 afs_int32
460 SVOTE_SDebugOld(struct rx_call * rxcall, afs_int32 awhich,
461                 register struct ubik_sdebug_old * aparm)
462 {
463     register struct ubik_server *ts;
464
465     for (ts = ubik_servers; ts; ts = ts->next) {
466         if (awhich-- == 0) {
467             /* we're done */
468             aparm->addr = ntohl(ts->addr[0]);   /* primary interface */
469             aparm->lastVoteTime = ts->lastVoteTime;
470             aparm->lastBeaconSent = ts->lastBeaconSent;
471             memcpy(&aparm->remoteVersion, &ts->version,
472                    sizeof(struct ubik_version));
473             aparm->lastVote = ts->lastVote;
474             aparm->up = ts->up;
475             aparm->beaconSinceDown = ts->beaconSinceDown;
476             aparm->currentDB = ts->currentDB;
477             return 0;
478         }
479     }
480     return 2;
481 }
482
483
484 /*!
485  * \brief Handle basic network debug command.  This is the global state dumper.
486  */
487 afs_int32
488 SVOTE_DebugOld(struct rx_call * rxcall,
489                register struct ubik_debug_old * aparm)
490 {
491
492     /* fill in the basic debug structure.  Note the the RPC protocol transfers,
493      * integers in host order. */
494
495     aparm->now = FT_ApproxTime();
496     aparm->lastYesTime = ubik_lastYesTime;
497     aparm->lastYesHost = ntohl(lastYesHost);
498     aparm->lastYesState = lastYesState;
499     aparm->lastYesClaim = lastYesClaim;
500     aparm->lowestHost = ntohl(lowestHost);
501     aparm->lowestTime = lowestTime;
502     aparm->syncHost = ntohl(syncHost);
503     aparm->syncTime = syncTime;
504
505     aparm->amSyncSite = ubik_amSyncSite;
506     ubeacon_Debug((ubik_debug *)aparm);
507
508     udisk_Debug((ubik_debug *)aparm);
509
510     ulock_Debug((ubik_debug *)aparm);
511
512     /* Get the recovery state. The label of the database may not have 
513      * been written yet but set the flag so udebug behavior remains.
514      * Defect 9477.
515      */
516     aparm->recoveryState = urecovery_state;
517     if ((urecovery_state & UBIK_RECSYNCSITE)
518         && (urecovery_state & UBIK_RECFOUNDDB)
519         && (urecovery_state & UBIK_RECHAVEDB)) {
520         aparm->recoveryState |= UBIK_RECLABELDB;
521     }
522     memcpy(&aparm->syncVersion, &ubik_dbVersion, sizeof(struct ubik_version));
523     memcpy(&aparm->syncTid, &ubik_dbTid, sizeof(struct ubik_tid));
524     aparm->activeWrite = (ubik_dbase->flags & DBWRITING);
525     aparm->tidCounter = ubik_dbase->tidCounter;
526
527     if (ubik_currentTrans) {
528         aparm->currentTrans = 1;
529         if (ubik_currentTrans->type == UBIK_WRITETRANS)
530             aparm->writeTrans = 1;
531         else
532             aparm->writeTrans = 0;
533     } else {
534         aparm->currentTrans = 0;
535     }
536
537     aparm->epochTime = ubik_epochTime;
538
539     return 0;
540 }
541
542
543 /*!
544  * \brief Get the sync site; called by remote servers to find where they should go.
545  */
546 afs_int32
547 SVOTE_GetSyncSite(register struct rx_call * rxcall,
548                   register afs_int32 * ahost)
549 {
550     register afs_int32 temp;
551
552     temp = uvote_GetSyncSite();
553     *ahost = ntohl(temp);
554     return 0;
555 }
556
557 void
558 ubik_dprint_25(const char *format, ...)
559 {
560     va_list ap;
561
562     va_start(ap, format);
563     vViceLog(25, (format, ap));
564     va_end(ap);
565 }
566
567 void
568 ubik_dprint(const char *format, ...)
569 {
570     va_list ap;
571
572     va_start(ap, format);
573     vViceLog(5, (format, ap));
574     va_end(ap);
575 }
576
577 void
578 ubik_vprint(const char *format, va_list ap)
579 {
580     vViceLog(0, (format, ap));
581 }
582
583 void
584 ubik_print(const char *format, ...)
585 {
586     va_list ap;
587
588     va_start(ap, format);
589     ubik_vprint(format, ap);
590     va_end(ap);
591 }
592
593 /*!
594  * \brief Called once/run to init the vote module
595  */
596 int
597 uvote_Init(void)
598 {
599     /* pretend we just voted for someone else, since we just restarted */
600     ubik_lastYesTime = FT_ApproxTime();
601     return 0;
602 }