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