2 * Copyright 2000, International Business Machines Corporation and others.
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
10 /* This file implements configuration functions in the following categories:
11 * cfg_BosServer*() - configure the BOS server.
12 * cfg_DbServers*() - configure the database servers.
13 * cfg_FileServer*() - configure the fileserver.
14 * cfg_UpdateServer*() - configure the update server.
15 * cfg_UpdateClient*() - configure update clients.
18 #include <afsconfig.h>
19 #include <afs/param.h>
28 #include <WINNT/afsreg.h>
29 #endif /* AFS_NT40_ENV */
34 #include <rx/rxstat.h>
36 #include <afs/afs_Admin.h>
37 #include <afs/afs_AdminErrors.h>
38 #include <afs/afs_bosAdmin.h>
39 #include <afs/afs_clientAdmin.h>
40 #include <afs/afs_utilAdmin.h>
41 #include <afs/afs_vosAdmin.h>
43 #include <afs/dirpath.h>
44 #include <afs/bnode.h>
45 #include <afs/cellconfig.h>
46 #include <afs/bubasics.h>
47 #include <rx/rx_null.h>
49 #define UBIK_INTERNALS /* need "internal" symbols from ubik.h */
52 #include "cfginternal.h"
53 #include "afs_cfgAdmin.h"
56 /* Local declarations and definitions */
58 #define KASERVER_BOSNAME "kaserver"
59 #define KASERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/kaserver"
61 #define PTSERVER_BOSNAME "ptserver"
62 #define PTSERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/ptserver"
64 #define VLSERVER_BOSNAME "vlserver"
65 #define VLSERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/vlserver"
67 #define BUSERVER_BOSNAME "buserver"
68 #define BUSERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/buserver"
70 #define UPSERVER_BOSNAME "upserver"
71 #define UPSERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/upserver"
73 #define UPCLIENT_BOSNAME "upclient"
74 #define UPCLIENT_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/upclient"
76 #define FILESERVER_BOSNAME "fs"
77 #define FILESERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/fileserver"
78 #define VOLSERVER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/volserver"
79 #define SALVAGER_EXEPATH AFSDIR_CANONICAL_SERVER_BIN_DIRPATH "/salvager"
83 SimpleProcessStart(void *bosHandle
, const char *instance
,
84 const char *executable
, const char *args
,
88 FsProcessStart(void *bosHandle
, const char *instance
,
89 const char *fileserverExe
, const char *volserverExe
,
90 const char *salvagerExe
, afs_status_p st
);
93 BosProcessDelete(void *bosHandle
, const char *instance
, afs_status_p st
);
96 UpdateCommandParse(char *cmdString
, short *hasSysPathP
, short *hasBinPathP
);
99 UbikQuorumCheck(cfg_host_p cfg_host
, const char *dbInstance
,
100 short *hasQuorum
, afs_status_p st
);
103 UbikVoteStatusFetch(int serverAddr
, unsigned short serverPort
,
104 short *isSyncSite
, short *isWriteReady
,
112 /* ---------------- Exported constants ---------------- */
114 const char *cfg_kaserverBosName
= KASERVER_BOSNAME
;
115 const char *cfg_ptserverBosName
= PTSERVER_BOSNAME
;
116 const char *cfg_vlserverBosName
= VLSERVER_BOSNAME
;
117 const char *cfg_buserverBosName
= BUSERVER_BOSNAME
;
118 const char *cfg_fileserverBosName
= FILESERVER_BOSNAME
;
119 const char *cfg_upserverBosName
= UPSERVER_BOSNAME
;
121 const char *cfg_upclientBosNamePrefix
= UPCLIENT_BOSNAME
;
122 const char *cfg_upclientSysBosSuffix
= "etc";
123 const char *cfg_upclientBinBosSuffix
= "bin";
127 /* ---------------- Exported BOS Server functions ------------------ */
131 * cfg_BosServerStart() -- Start the BOS server on host.
133 * Timeout is the maximum time, in seconds, to wait for BOS to start.
136 cfg_BosServerStart(void *hostHandle
, /* host config handle */
137 short noAuth
, /* start in NoAuth mode */
138 unsigned int timeout
, /* timeout (in seconds) */
140 { /* completion status */
142 afs_status_t tst2
, tst
= 0;
143 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
144 short wasRunning
= 0;
146 /* validate parameters */
148 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
152 /* remote configuration not yet supported in this function */
155 if (!cfg_host
->is_local
) {
156 tst
= ADMCFGNOTSUPPORTED
;
160 /* start bosserver (if not already running) */
163 /* Windows - bosserver is controlled via the BOS control service */
166 LPCTSTR auxArgBuf
[1], *auxArgv
;
171 auxArgBuf
[0] = "-noauth";
177 if (!cfgutil_WindowsServiceStart
178 (AFSREG_SVR_SVC_NAME
, auxArgc
, auxArgv
, timeout
, &wasRunning
,
180 /* failed to start BOS control service */
186 /* function not yet implemented for Unix */
187 tst
= ADMCFGNOTSUPPORTED
;
189 #endif /* AFS_NT40_ENV */
191 /* put bosserver into requested auth mode if was already running */
193 if (tst
== 0 && wasRunning
) {
194 if (!cfgutil_HostSetNoAuthFlag(cfg_host
, noAuth
, &tst2
)) {
200 /* indicate failure */
212 * cfg_BosServerStop() -- Stop the BOS server on host.
214 * Timeout is the maximum time, in seconds, to wait for BOS to stop.
217 cfg_BosServerStop(void *hostHandle
, /* host config handle */
218 unsigned int timeout
, /* timeout (in seconds) */
220 { /* completion status */
222 afs_status_t tst2
, tst
= 0;
223 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
225 /* validate parameters */
227 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
231 /* remote configuration not yet supported in this function */
234 if (!cfg_host
->is_local
) {
235 tst
= ADMCFGNOTSUPPORTED
;
239 /* stop the bosserver (if running) */
242 /* Windows - bosserver is controlled via the BOS control service */
246 if (!cfgutil_WindowsServiceStop
247 (AFSREG_SVR_SVC_NAME
, timeout
, &wasStopped
, &tst2
)) {
248 /* failed to stop BOS control service */
254 /* function not yet implemented for Unix */
255 tst
= ADMCFGNOTSUPPORTED
;
257 #endif /* AFS_NT40_ENV */
260 /* indicate failure */
271 * cfg_BosServerQueryStatus() -- Query status of BOS server on host.
273 * The argument *isBosProcP is set to TRUE only if BOS processes
274 * are currently executing (as opposed to configured but stopped).
277 cfg_BosServerQueryStatus(void *hostHandle
, /* host config handle */
278 short *isStartedP
, /* BOS server is started */
279 short *isBosProcP
, /* BOS processes running */
281 { /* completion status */
283 afs_status_t tst2
, tst
= 0;
284 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
286 /* validate parameters and prepare host handle for bos functions */
288 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
290 } else if (isStartedP
== NULL
) {
291 tst
= ADMCFGSTARTEDFLAGPNULL
;
292 } else if (isBosProcP
== NULL
) {
293 tst
= ADMCFGBOSSERVERPROCSFLAGPNULL
;
294 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
298 /* remote configuration not yet supported in this function */
301 if (!cfg_host
->is_local
) {
302 tst
= ADMCFGNOTSUPPORTED
;
306 /* determine if bosserver is running */
309 /* Windows - bosserver is controlled via the BOS control service */
313 *isStartedP
= *isBosProcP
= 0;
315 if (!cfgutil_WindowsServiceQuery
316 (AFSREG_SVR_SVC_NAME
, &svcState
, &tst2
)) {
318 } else if (svcState
== SERVICE_RUNNING
) {
324 /* function not yet implemented for Unix */
325 tst
= ADMCFGNOTSUPPORTED
;
327 #endif /* AFS_NT40_ENV */
330 /* query status of bos processes */
332 if (tst
== 0 && *isStartedP
) {
337 if (!bos_ProcessNameGetBegin(cfg_host
->bosHandle
, &procIter
, &tst2
)) {
340 /* iterate over process names, checking status of each */
341 char procName
[BOS_MAX_NAME_LEN
];
342 bos_ProcessExecutionState_t procState
;
343 char procAuxState
[BOS_MAX_NAME_LEN
];
347 if (!bos_ProcessNameGetNext(procIter
, procName
, &tst2
)) {
348 /* no more processes (or failure) */
349 if (tst2
!= ADMITERATORDONE
) {
355 if (!bos_ProcessExecutionStateGet
356 (cfg_host
->bosHandle
, procName
, &procState
,
357 procAuxState
, &tst2
)) {
358 /* process removed (or failure) */
359 if (tst2
!= BZNOENT
) {
365 if (procState
!= BOS_PROCESS_STOPPED
) {
372 if (!bos_ProcessNameGetDone(procIter
, &tst2
)) {
379 /* indicate failure */
391 /* ---------------- Exported Database Server functions ------------------ */
396 * cfg_AuthServerStart() -- Start authentication server on host and wait
397 * for server to be ready to accept requests.
399 * This function is intended to be used when configuring the first
400 * machine in a cell; it enables the AFS server principal to be created
401 * and configured before starting the remaining database servers.
404 cfg_AuthServerStart(void *hostHandle
, /* host config handle */
406 { /* completion status */
408 afs_status_t tst2
, tst
= 0;
409 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
411 /* validate parameters and prepare host handle for bos functions */
413 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
415 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
419 /* create and start authentication server instance */
422 if (!SimpleProcessStart
423 (cfg_host
->bosHandle
, KASERVER_BOSNAME
, KASERVER_EXEPATH
, NULL
,
429 /* wait for authentication server to achieve quorum */
432 time_t timeStart
= time(NULL
);
437 (cfg_host
, KASERVER_BOSNAME
, &kaHasQuorum
, &tst2
)) {
441 } else if (kaHasQuorum
) {
442 /* quorum on authentication server */
446 /* quorum not yet achieved on authentication server */
447 if (difftime(time(NULL
), timeStart
) > 180) {
448 tst
= ADMCFGQUORUMWAITTIMEOUT
;
458 /* indicate failure */
469 * cfg_DbServersStart() -- Start the standard (required) database servers,
470 * and optionally the backup database server, on host.
472 * The BOS instance names used are the string constants:
473 * cfg_kaserverBosName - authentication server
474 * cfg_ptserverBosName - protection server
475 * cfg_vlserverBosName - volume location server
476 * cfg_buserverBosName - backup server
479 cfg_DbServersStart(void *hostHandle
, /* host config handle */
480 short startBkDb
, /* start backup server */
482 { /* completion status */
484 afs_status_t tst2
, tst
= 0;
485 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
487 /* validate parameters and prepare host handle for bos functions */
489 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
491 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
495 /* create and start database server instances */
498 /* try all regardless of failures; last error code wins */
499 if (!SimpleProcessStart
500 (cfg_host
->bosHandle
, KASERVER_BOSNAME
, KASERVER_EXEPATH
, NULL
,
504 if (!SimpleProcessStart
505 (cfg_host
->bosHandle
, PTSERVER_BOSNAME
, PTSERVER_EXEPATH
, NULL
,
509 if (!SimpleProcessStart
510 (cfg_host
->bosHandle
, VLSERVER_BOSNAME
, VLSERVER_EXEPATH
, NULL
,
515 && !SimpleProcessStart(cfg_host
->bosHandle
, BUSERVER_BOSNAME
,
516 BUSERVER_EXEPATH
, NULL
, &tst2
)) {
522 /* indicate failure */
533 * cfg_DbServersStop() -- Stop, and unconfigure, the database servers on host.
536 cfg_DbServersStop(void *hostHandle
, /* host config handle */
538 { /* completion status */
540 afs_status_t tst2
, tst
= 0;
541 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
543 /* validate parameters and prepare host handle for bos functions */
545 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
547 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
551 /* stop and delete database server instances */
554 /* try all regardless of failures; last error code wins */
555 if (!BosProcessDelete(cfg_host
->bosHandle
, KASERVER_BOSNAME
, &tst2
)) {
558 if (!BosProcessDelete(cfg_host
->bosHandle
, PTSERVER_BOSNAME
, &tst2
)) {
561 if (!BosProcessDelete(cfg_host
->bosHandle
, VLSERVER_BOSNAME
, &tst2
)) {
564 if (!BosProcessDelete(cfg_host
->bosHandle
, BUSERVER_BOSNAME
, &tst2
)) {
570 /* indicate failure */
581 * cfg_DbServersQueryStatus() -- Query status of database servers on host.
583 * If detailed status information is not required, detailsP can be NULL.
585 * If *isStdDbP is FALSE and *isBkDbP is TRUE then the host is in an
586 * inconsistent state; the remaining database servers should be configured.
589 cfg_DbServersQueryStatus(void *hostHandle
, /* host config handle */
590 short *isStdDbP
, /* std DB servers configured */
591 short *isBkDbP
, /* backup DB server configured */
592 cfg_dbServersStatus_t
* detailsP
, /* config details */
594 { /* completion status */
596 afs_status_t tst2
, tst
= 0;
597 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
598 short inCellServDb
, isKaserver
, isPtserver
, isVlserver
, isBuserver
;
600 inCellServDb
= isKaserver
= isPtserver
= isVlserver
= isBuserver
= 0;
602 /* validate parameters and prepare host handle for bos functions */
604 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
606 } else if (isStdDbP
== NULL
|| isBkDbP
== NULL
) {
607 tst
= ADMCFGDBSERVERCONFIGFLAGPNULL
;
608 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
612 /* query host's server CellServDb to see if it lists itself */
615 char hostNameAlias
[MAXHOSTCHARS
];
617 if (!cfgutil_HostNameGetCellServDbAlias
618 (cfg_host
->hostName
, cfg_host
->hostName
, hostNameAlias
, &tst2
)) {
620 } else if (*hostNameAlias
!= '\0') {
621 /* host in its own CellServDb */
626 /* query bosserver to determine what database servers are configured */
629 bos_ProcessType_t procType
;
630 bos_ProcessInfo_t procInfo
;
632 if (bos_ProcessInfoGet
633 (cfg_host
->bosHandle
, KASERVER_BOSNAME
, &procType
, &procInfo
,
636 } else if (tst2
!= BZNOENT
) {
641 if (bos_ProcessInfoGet
642 (cfg_host
->bosHandle
, PTSERVER_BOSNAME
, &procType
, &procInfo
,
645 } else if (tst2
!= BZNOENT
) {
651 if (bos_ProcessInfoGet
652 (cfg_host
->bosHandle
, VLSERVER_BOSNAME
, &procType
, &procInfo
,
655 } else if (tst2
!= BZNOENT
) {
661 if (bos_ProcessInfoGet
662 (cfg_host
->bosHandle
, BUSERVER_BOSNAME
, &procType
, &procInfo
,
665 } else if (tst2
!= BZNOENT
) {
672 /* success; return results */
673 *isStdDbP
= (inCellServDb
&& isKaserver
&& isPtserver
&& isVlserver
);
674 *isBkDbP
= (inCellServDb
&& isBuserver
);
677 detailsP
->inCellServDb
= inCellServDb
;
678 detailsP
->isKaserver
= isKaserver
;
679 detailsP
->isPtserver
= isPtserver
;
680 detailsP
->isVlserver
= isVlserver
;
681 detailsP
->isBuserver
= isBuserver
;
684 /* indicate failure */
695 * cfg_DbServersRestartAll() -- Restart all database servers in host's cell.
698 cfg_DbServersRestartAll(void *hostHandle
, /* host config handle */
700 { /* completion status */
702 afs_status_t tst2
, tst
= 0;
703 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
705 /* validate parameters and prepare host handle for bos functions */
707 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
709 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
713 /* restart all database servers in host's cell */
718 if (!bos_HostGetBegin(cfg_host
->bosHandle
, &dbIter
, &tst2
)) {
721 /* iterate over server CellServDb, restarting db servers */
722 char dbhostName
[BOS_MAX_NAME_LEN
];
726 while (!dbhostDone
) {
727 if (!bos_HostGetNext(dbIter
, dbhostName
, &tst2
)) {
728 /* no more entries (or failure) */
729 if (tst2
!= ADMITERATORDONE
) {
736 (cfg_host
->cellHandle
, dbhostName
, &dbhostHandle
,
738 /* failed to get bos handle; note error but keep going */
742 /* restart db servers; note errors, but keep going */
743 if (!bos_ProcessRestart
744 (dbhostHandle
, KASERVER_BOSNAME
, &tst2
)) {
747 if (!bos_ProcessRestart
748 (dbhostHandle
, PTSERVER_BOSNAME
, &tst2
)) {
751 if (!bos_ProcessRestart
752 (dbhostHandle
, VLSERVER_BOSNAME
, &tst2
)) {
755 if (!bos_ProcessRestart
756 (dbhostHandle
, BUSERVER_BOSNAME
, &tst2
)) {
757 /* may not be running a backup server */
758 if (tst2
!= BZNOENT
) {
763 if (!bos_ServerClose(dbhostHandle
, &tst2
)) {
769 if (!bos_HostGetDone(dbIter
, &tst2
)) {
776 /* indicate failure */
779 /* should really utilize a callback (or some other mechanism) to
780 * indicate which restarts failed and why.
791 * cfg_DbServersWaitForQuorum() -- Wait for database servers in host's cell
794 * Timeout is the maximum time, in seconds, to wait for quorum.
796 * NOTE: Function does not check for backup server quorum since
797 * configuration does not require modifying the backup database.
800 cfg_DbServersWaitForQuorum(void *hostHandle
, /* host config handle */
801 unsigned int timeout
, /* timeout in sec. */
803 { /* completion status */
805 afs_status_t tst2
, tst
= 0;
806 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
808 /* validate parameters and prepare host handle for bos functions */
810 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
812 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
816 /* wait for the database servers in host's cell to achieve quorum */
819 time_t timeStart
= time(NULL
);
820 short kaHasQuorum
, ptHasQuorum
, vlHasQuorum
;
822 kaHasQuorum
= ptHasQuorum
= vlHasQuorum
= 0;
827 (cfg_host
, KASERVER_BOSNAME
, &kaHasQuorum
, &tst2
)) {
835 (cfg_host
, PTSERVER_BOSNAME
, &ptHasQuorum
, &tst2
)) {
843 (cfg_host
, VLSERVER_BOSNAME
, &vlHasQuorum
, &tst2
)) {
849 if (kaHasQuorum
&& ptHasQuorum
&& vlHasQuorum
) {
850 /* quorum on all dbservers of interest */
853 /* quorum not yet achieved for one or more dbservers */
855 || (difftime(time(NULL
), timeStart
) > timeout
)) {
856 tst
= ADMCFGQUORUMWAITTIMEOUT
;
866 /* indicate failure */
878 * cfg_DbServersStopAllBackup() -- Stop, and unconfigure, all backup servers
882 cfg_DbServersStopAllBackup(void *hostHandle
, /* host config handle */
884 { /* completion status */
886 afs_status_t tst2
, tst
= 0;
887 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
889 /* validate parameters and prepare host handle for bos functions */
891 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
893 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
897 /* stop and delete all backup servers in host's cell */
902 if (!bos_HostGetBegin(cfg_host
->bosHandle
, &dbIter
, &tst2
)) {
905 /* iterate over server CellServDb, unconfiguring backup servers */
906 char dbhostName
[BOS_MAX_NAME_LEN
];
910 while (!dbhostDone
) {
911 if (!bos_HostGetNext(dbIter
, dbhostName
, &tst2
)) {
912 /* no more entries (or failure) */
913 if (tst2
!= ADMITERATORDONE
) {
920 (cfg_host
->cellHandle
, dbhostName
, &dbhostHandle
,
922 /* failed to get bos handle; note error but keep going */
926 /* unconfig backup server; note errors, but keep going */
927 if (!BosProcessDelete
928 (dbhostHandle
, BUSERVER_BOSNAME
, &tst2
)) {
932 if (!bos_ServerClose(dbhostHandle
, &tst2
)) {
938 if (!bos_HostGetDone(dbIter
, &tst2
)) {
945 /* indicate failure */
948 /* should really utilize a callback (or some other mechanism) to
949 * indicate which stops failed and why.
962 /* ---------------- Exported File Server functions ------------------ */
966 * cfg_FileServerStart() -- Start the file server on host.
968 * The BOS instance name used is the string constant cfg_fileserverBosName.
971 cfg_FileServerStart(void *hostHandle
, /* host config handle */
973 { /* completion status */
975 afs_status_t tst2
, tst
= 0;
976 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
978 /* validate parameters and prepare host handle for bos functions */
980 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
982 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
986 /* create and start file server instance */
990 (cfg_host
->bosHandle
, FILESERVER_BOSNAME
, FILESERVER_EXEPATH
,
991 VOLSERVER_EXEPATH
, SALVAGER_EXEPATH
, &tst2
)) {
994 /* TO BE DONE: need a reliable "is started and ready" check */
1000 /* indicate failure */
1011 * cfg_FileServerStop() -- Stop, and unconfigure, the file server on host.
1014 cfg_FileServerStop(void *hostHandle
, /* host config handle */
1016 { /* completion status */
1018 afs_status_t tst2
, tst
= 0;
1019 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1021 /* validate parameters and prepare host handle for bos functions */
1023 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1025 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1029 /* stop and delete file server instance */
1032 if (!BosProcessDelete(cfg_host
->bosHandle
, FILESERVER_BOSNAME
, &tst2
)) {
1035 /* file server instance deleted; remove its addresses from VLDB */
1037 afs_int32
*addrList
= NULL
;
1039 /* note: ignore any errors since address removal is optional;
1040 * e.g., a common source of errors will be attempting to remove
1041 * an address while volumes tied to that address are still listed
1042 * in the VLDB (in which case the address is not removed).
1044 if (cfgutil_HostAddressFetchAll
1045 (cfg_host
->hostName
, &addrCount
, &addrList
, &tst2
)) {
1046 for (i
= 0; i
< addrCount
; i
++) {
1047 (void)vos_FileServerAddressRemove(cfg_host
->cellHandle
,
1060 /* indicate failure */
1071 * cfg_FileServerQueryStatus() -- Query status of file server on host.
1074 cfg_FileServerQueryStatus(void *hostHandle
, /* host config handle */
1075 short *isFsP
, /* file server configured */
1077 { /* completion status */
1079 afs_status_t tst2
, tst
= 0;
1080 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1082 /* validate parameters and prepare host handle for bos functions */
1084 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1086 } else if (isFsP
== NULL
) {
1087 tst
= ADMCFGFILESERVERCONFIGFLAGPNULL
;
1088 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1092 /* query bosserver to determine if fileserver is configured */
1095 bos_ProcessType_t procType
;
1096 bos_ProcessInfo_t procInfo
;
1100 if (bos_ProcessInfoGet
1101 (cfg_host
->bosHandle
, FILESERVER_BOSNAME
, &procType
, &procInfo
,
1103 /* instance exists; check type for good measure */
1104 if (procType
== BOS_PROCESS_FS
) {
1107 } else if (tst2
!= BZNOENT
) {
1113 /* indicate failure */
1125 /* ---------------- Exported Update Server functions ------------------ */
1130 * cfg_UpdateServerStart() -- Start the Update server on host.
1132 * Argument strings exportClear and exportCrypt each specify a set of
1133 * space-separated directories to export or are NULL.
1135 * The BOS instance name used is the string constant cfg_upserverBosName.
1138 cfg_UpdateServerStart(void *hostHandle
, /* host config handle */
1139 const char *exportClear
, /* dirs to export in clear */
1140 const char *exportCrypt
, /* dirs to export encrypted */
1142 { /* completion status */
1144 afs_status_t tst2
, tst
= 0;
1145 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1147 /* validate parameters and prepare host handle for bos functions */
1149 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1151 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1155 /* stop and delete existing update server instance, if any.
1156 * we do this because the set of exported directores might be changing.
1160 if (!BosProcessDelete(cfg_host
->bosHandle
, UPSERVER_BOSNAME
, &tst2
)) {
1165 /* create and start update server instance */
1171 if (exportClear
!= NULL
&& *exportClear
!= '\0') {
1172 if (exportCrypt
!= NULL
&& *exportCrypt
!= '\0') {
1173 r
= asprintf(&args
, "-clear %s -crypt %s",
1174 exportClear
, exportCrypt
);
1176 r
= asprintf(&args
, "-clear %s", exportClear
);
1179 if (exportCrypt
!= NULL
&& *exportCrypt
!= '\0') {
1180 r
= asprintf(&args
, "-crypt %s", exportCrypt
);
1192 if (!SimpleProcessStart
1193 (cfg_host
->bosHandle
, UPSERVER_BOSNAME
, UPSERVER_EXEPATH
,
1202 /* indicate failure */
1213 * cfg_UpdateServerStop() -- Stop, and unconfigure, the Update server on host.
1216 cfg_UpdateServerStop(void *hostHandle
, /* host config handle */
1218 { /* completion status */
1220 afs_status_t tst2
, tst
= 0;
1221 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1223 /* validate parameters and prepare host handle for bos functions */
1225 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1227 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1231 /* stop and delete upserver instance */
1234 if (!BosProcessDelete(cfg_host
->bosHandle
, UPSERVER_BOSNAME
, &tst2
)) {
1240 /* indicate failure */
1251 * cfg_UpdateServerQueryStatus() -- Query status of Update server on host.
1254 cfg_UpdateServerQueryStatus(void *hostHandle
, /* host config handle */
1255 short *isUpserverP
, /* update server configured */
1256 short *isSysCtrlP
, /* system control configured */
1257 short *isBinDistP
, /* binary dist configured */
1259 { /* completion status */
1261 afs_status_t tst2
, tst
= 0;
1262 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1264 /* validate parameters and prepare host handle for bos functions */
1266 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1268 } else if (isUpserverP
== NULL
|| isSysCtrlP
== NULL
1269 || isBinDistP
== NULL
) {
1270 tst
= ADMCFGUPSERVERCONFIGFLAGPNULL
;
1271 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1275 /* query bosserver to determine if, and how, upserver is configured */
1280 *isUpserverP
= *isSysCtrlP
= *isBinDistP
= 0;
1282 if (!bos_ProcessParameterGetBegin
1283 (cfg_host
->bosHandle
, UPSERVER_BOSNAME
, &cmdIter
, &tst2
)) {
1286 char cmdString
[BOS_MAX_NAME_LEN
];
1288 if (!bos_ProcessParameterGetNext(cmdIter
, cmdString
, &tst2
)) {
1289 /* no upserver instance (or error) */
1290 if (tst2
!= BZNOENT
) {
1294 /* parse upserver command line to determine how configured */
1295 short hasSysPath
, hasBinPath
;
1297 UpdateCommandParse(cmdString
, &hasSysPath
, &hasBinPath
);
1309 if (!bos_ProcessParameterGetDone(cmdIter
, &tst2
)) {
1316 /* indicate failure */
1327 * cfg_SysBinServerStart() -- Start Update server in System Control and/or
1328 * Binary Distribution machine configuration on host.
1330 * This function is a convenience wrapper for cfg_UpdateServerStart().
1333 cfg_SysBinServerStart(void *hostHandle
, /* host config handle */
1334 short makeSysCtrl
, /* config as sys control mach */
1335 short makeBinDist
, /* config as binary dist mach */
1337 { /* completion status */
1338 char *cryptSysDir
= NULL
;
1339 char *clearBinDir
= NULL
;
1342 cryptSysDir
= AFSDIR_CANONICAL_SERVER_ETC_DIRPATH
;
1346 clearBinDir
= AFSDIR_CANONICAL_SERVER_BIN_DIRPATH
;
1349 return cfg_UpdateServerStart(hostHandle
, clearBinDir
, cryptSysDir
, st
);
1354 /* ---------------- Exported Update Client functions ------------------ */
1359 * cfg_UpdateClientStart() -- Start an Update client on host.
1361 * Argument string import specifies a set of space-separated directories
1362 * to import. Argument frequency specifies the import interval in
1363 * seconds; if the value is zero (0) then the default frequency is used.
1365 * The BOS instance name used is the concatenation of the string constant
1366 * cfg_upclientBosNamePrefix and the argument string bosSuffix.
1369 cfg_UpdateClientStart(void *hostHandle
, /* host config handle */
1370 const char *bosSuffix
, /* BOS instance suffix */
1371 const char *upserver
, /* upserver to import from */
1372 short crypt
, /* import encrypted */
1373 const char *import
, /* dirs to import */
1374 unsigned int frequency
, /* import interval in sec. */
1376 { /* completion status */
1378 afs_status_t tst2
, tst
= 0;
1379 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1380 char upclientInstance
[BOS_MAX_NAME_LEN
];
1382 /* validate parameters and prepare host handle for bos functions */
1384 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1386 } else if (bosSuffix
== NULL
) {
1387 tst
= ADMCFGUPCLIENTSUFFIXNULL
;
1388 } else if ((strlen(UPCLIENT_BOSNAME
) + strlen(bosSuffix
) + 1) >
1390 tst
= ADMCFGUPCLIENTSUFFIXTOOLONG
;
1391 } else if (upserver
== NULL
|| *upserver
== '\0') {
1392 tst
= ADMCFGUPCLIENTTARGETSERVERNULL
;
1393 } else if (import
== NULL
|| *import
== '\0') {
1394 tst
= ADMCFGUPCLIENTIMPORTDIRNULL
;
1395 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1399 /* stop and delete existing update client instance, if any.
1400 * we do this because the set of imported directores might be changing.
1404 sprintf(upclientInstance
, "%s%s", UPCLIENT_BOSNAME
, bosSuffix
);
1406 if (!BosProcessDelete(cfg_host
->bosHandle
, upclientInstance
, &tst2
)) {
1411 /* create and start update client instance */
1418 r
= asprintf(&args
, "%s %s -t %u %s", upserver
,
1419 crypt
? "-crypt" : "-clear", frequency
, import
);
1421 r
= asprintf(&args
, "%s %s %s", upserver
,
1422 crypt
? "-crypt" : "-clear", import
);
1428 /* create and start instance */
1429 if (!SimpleProcessStart
1430 (cfg_host
->bosHandle
, upclientInstance
, UPCLIENT_EXEPATH
,
1439 /* indicate failure */
1450 * cfg_UpdateClientStop() -- Stop, and unconfigure, an Update client on host.
1453 cfg_UpdateClientStop(void *hostHandle
, /* host config handle */
1454 const char *bosSuffix
, /* BOS instance suffix */
1456 { /* completion status */
1458 afs_status_t tst2
, tst
= 0;
1459 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1460 char upclientInstance
[BOS_MAX_NAME_LEN
];
1462 /* validate parameters and prepare host handle for bos functions */
1464 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1466 } else if (bosSuffix
== NULL
) {
1467 tst
= ADMCFGUPCLIENTSUFFIXNULL
;
1468 } else if ((strlen(UPCLIENT_BOSNAME
) + strlen(bosSuffix
) + 1) >
1470 tst
= ADMCFGUPCLIENTSUFFIXTOOLONG
;
1471 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1475 /* stop and delete specified update client instance */
1478 sprintf(upclientInstance
, "%s%s", UPCLIENT_BOSNAME
, bosSuffix
);
1480 if (!BosProcessDelete(cfg_host
->bosHandle
, upclientInstance
, &tst2
)) {
1486 /* indicate failure */
1497 * cfg_UpdateClientStopAll() -- Stop, and unconfigure, all Update clients
1501 cfg_UpdateClientStopAll(void *hostHandle
, /* host config handle */
1503 { /* completion status */
1505 afs_status_t tst2
, tst
= 0;
1506 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1508 /* validate parameters and prepare host handle for bos functions */
1510 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1512 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1516 /* find, stop, and delete all update client instances */
1521 if (!bos_ProcessNameGetBegin(cfg_host
->bosHandle
, &procIter
, &tst2
)) {
1524 /* iterate over process names, looking for update clients */
1525 char procName
[BOS_MAX_NAME_LEN
];
1529 if (!bos_ProcessNameGetNext(procIter
, procName
, &tst2
)) {
1530 /* no more processes (or failure) */
1531 if (tst2
!= ADMITERATORDONE
) {
1538 (UPCLIENT_BOSNAME
, procName
,
1539 (sizeof(UPCLIENT_BOSNAME
) - 1))) {
1540 /* upclient instance prefix; assume is upclient */
1541 if (!BosProcessDelete
1542 (cfg_host
->bosHandle
, procName
, &tst2
)) {
1549 if (!bos_ProcessNameGetDone(procIter
, &tst2
)) {
1556 /* indicate failure */
1567 * cfg_UpdateClientQueryStatus() -- Query status of Update clients on host.
1570 cfg_UpdateClientQueryStatus(void *hostHandle
, /* host config handle */
1571 short *isUpclientP
, /* an upclient is configured */
1572 short *isSysP
, /* system control client */
1573 short *isBinP
, /* binary dist. client */
1575 { /* completion status */
1577 afs_status_t tst2
, tst
= 0;
1578 cfg_host_p cfg_host
= (cfg_host_p
) hostHandle
;
1580 /* validate parameters and prepare host handle for bos functions */
1582 if (!cfgutil_HostHandleValidate(cfg_host
, &tst2
)) {
1584 } else if (isUpclientP
== NULL
|| isSysP
== NULL
|| isBinP
== NULL
) {
1585 tst
= ADMCFGUPCLIENTCONFIGFLAGPNULL
;
1586 } else if (!cfgutil_HostHandleBosInit(cfg_host
, &tst2
)) {
1590 /* determine if, and how, any upclients are configured */
1595 *isUpclientP
= *isSysP
= *isBinP
= 0;
1597 if (!bos_ProcessNameGetBegin(cfg_host
->bosHandle
, &procIter
, &tst2
)) {
1600 /* iterate over process names, looking for update clients */
1601 char procName
[BOS_MAX_NAME_LEN
];
1605 if (!bos_ProcessNameGetNext(procIter
, procName
, &tst2
)) {
1606 /* no more processes (or failure) */
1607 if (tst2
!= ADMITERATORDONE
) {
1614 (UPCLIENT_BOSNAME
, procName
,
1615 (sizeof(UPCLIENT_BOSNAME
) - 1))) {
1616 /* upclient instance prefix; assume is upclient */
1621 if (!bos_ProcessParameterGetBegin
1622 (cfg_host
->bosHandle
, procName
, &cmdIter
, &tst2
)) {
1625 char cmdString
[BOS_MAX_NAME_LEN
];
1627 if (!bos_ProcessParameterGetNext
1628 (cmdIter
, cmdString
, &tst2
)) {
1629 /* instance deleted out from under us (or error) */
1630 if (tst2
!= BZNOENT
) {
1634 /* parse command line to determine how config */
1635 short hasSysPath
, hasBinPath
;
1637 UpdateCommandParse(cmdString
, &hasSysPath
,
1648 if (!bos_ProcessParameterGetDone(cmdIter
, &tst2
)) {
1659 if (!bos_ProcessNameGetDone(procIter
, &tst2
)) {
1666 /* indicate failure */
1677 * cfg_SysControlClientStart() -- Start an Update client in System Control
1678 * client configuration on host.
1680 * This function is a convenience wrapper for cfg_UpdateClientStart().
1681 * The BOS instance suffix used is the constant cfg_upclientSysBosSuffix.
1684 cfg_SysControlClientStart(void *hostHandle
, /* host config handle */
1685 const char *upserver
, /* upserver to import from */
1687 { /* completion status */
1688 return cfg_UpdateClientStart(hostHandle
, cfg_upclientSysBosSuffix
,
1689 upserver
, 1 /* crypt */ ,
1690 AFSDIR_CANONICAL_SERVER_ETC_DIRPATH
,
1691 0 /* default frequency */ ,
1697 * cfg_BinDistClientStart() -- Start an Update client in Binary Distribution
1698 * client configuration on host.
1700 * This function is a convenience wrapper for cfg_UpdateClientStart().
1701 * The BOS instance suffix used is the constant cfg_upclientBinBosSuffix.
1704 cfg_BinDistClientStart(void *hostHandle
, /* host config handle */
1705 const char *upserver
, /* upserver to import from */
1707 { /* completion status */
1708 return cfg_UpdateClientStart(hostHandle
, cfg_upclientBinBosSuffix
,
1709 upserver
, 0 /* crypt */ ,
1710 AFSDIR_CANONICAL_SERVER_BIN_DIRPATH
,
1711 0 /* default frequency */ ,
1717 /* ---------------- Local functions ------------------ */
1720 * SimpleProcessStart() -- create and start a simple bosserver instance.
1722 * RETURN CODES: 1 success, 0 failure (st indicates why)
1725 SimpleProcessStart(void *bosHandle
, const char *instance
,
1726 const char *executable
, const char *args
, afs_status_p st
)
1729 afs_status_t tst2
, tst
= 0;
1733 cmd
= strdup(executable
);
1735 if (asprintf(&cmd
, "%s %s", executable
, args
) < 0)
1742 if (!bos_ProcessCreate
1743 (bosHandle
, (char *)instance
, BOS_PROCESS_SIMPLE
, cmd
, NULL
, NULL
, &tst2
)
1744 && tst2
!= BZEXISTS
) {
1745 /* failed to create instance (and not because existed) */
1748 if (!bos_ProcessExecutionStateSet
1749 (bosHandle
, (char *)instance
, BOS_PROCESS_RUNNING
, &tst2
)) {
1750 /* failed to set instance state to running */
1757 /* indicate failure */
1769 * FsProcessStart() -- create and start a fs bosserver instance.
1771 * RETURN CODES: 1 success, 0 failure (st indicates why)
1774 FsProcessStart(void *bosHandle
, const char *instance
,
1775 const char *fileserverExe
, const char *volserverExe
,
1776 const char *salvagerExe
, afs_status_p st
)
1779 afs_status_t tst2
, tst
= 0;
1781 if (!bos_FSProcessCreate
1782 (bosHandle
, (char *)instance
, (char *)fileserverExe
, (char *)volserverExe
, (char *)salvagerExe
, NULL
,
1783 &tst2
) && tst2
!= BZEXISTS
) {
1784 /* failed to create instance (and not because existed) */
1787 if (!bos_ProcessExecutionStateSet
1788 (bosHandle
, instance
, BOS_PROCESS_RUNNING
, &tst2
)) {
1789 /* failed to set instance state to running */
1794 /* indicate failure */
1806 * BosProcessDelete() -- stop and delete a bosserver instance, if it exists.
1808 * RETURN CODES: 1 success, 0 failure (st indicates why)
1811 BosProcessDelete(void *bosHandle
, const char *instance
, afs_status_p st
)
1814 afs_status_t tst2
, tst
= 0;
1816 if (!bos_ProcessExecutionStateSet
1817 (bosHandle
, instance
, BOS_PROCESS_STOPPED
, &tst2
)) {
1818 /* failed to set instance state to stopped (or does not exist) */
1819 if (tst2
!= BZNOENT
) {
1823 } else if (!bos_ProcessAllWaitTransition(bosHandle
, &tst2
)) {
1824 /* failed to wait for process to stop */
1827 } else if (!bos_ProcessDelete(bosHandle
, (char *)instance
, &tst2
)) {
1828 /* failed to delete instance (or does not exist) */
1829 if (tst2
!= BZNOENT
) {
1835 /* indicate failure */
1846 * UpdateCommandParse() -- Parse an upserver or upclient command to determine:
1847 * 1) if it explicitly exports/imports the system control directory
1848 * 2) if it explicitly exports/imports the binary directory
1850 * NOTE: cmdString altered (made all lower case and forward slashes)
1853 UpdateCommandParse(char *cmdString
, short *hasSysPathP
, short *hasBinPathP
)
1857 *hasSysPathP
= *hasBinPathP
= 0;
1859 /* make command string all lower case and forward slashes */
1861 for (argp
= cmdString
; *argp
!= '\0'; argp
++) {
1862 if (isupper(*argp
)) {
1863 *argp
= tolower(*argp
);
1864 } else if (*argp
== '\\') {
1869 /* find end of update executable path (and hence beginning of arguments */
1873 while (isspace(*argp
)) {
1876 while (*argp
!= '\0' && !isspace(*argp
)) {
1880 /* search for well-known system control directory */
1882 dirp
= strstr(argp
, AFSDIR_CANONICAL_SERVER_ETC_DIRPATH
);
1885 /* check that not a portition of a larger path */
1886 char oneBefore
, oneAfter
;
1889 oneBefore
= *(dirp
- 1);
1890 oneAfter
= *(dirp
+ sizeof(AFSDIR_CANONICAL_SERVER_ETC_DIRPATH
) - 1);
1892 if (oneAfter
!= '\0') {
1893 twoAfter
= *(dirp
+ sizeof(AFSDIR_CANONICAL_SERVER_ETC_DIRPATH
));
1896 if (isspace(oneBefore
)) {
1897 if ((isspace(oneAfter
)) || (oneAfter
== '\0')
1899 && (isspace(twoAfter
) || twoAfter
== '\0'))) {
1905 /* search for well-known binary directory */
1907 dirp
= strstr(argp
, AFSDIR_CANONICAL_SERVER_BIN_DIRPATH
);
1910 /* check that not a portition of a larger path */
1911 char oneBefore
, oneAfter
;
1914 oneBefore
= *(dirp
- 1);
1915 oneAfter
= *(dirp
+ sizeof(AFSDIR_CANONICAL_SERVER_BIN_DIRPATH
) - 1);
1917 if (oneAfter
!= '\0') {
1918 twoAfter
= *(dirp
+ sizeof(AFSDIR_CANONICAL_SERVER_BIN_DIRPATH
));
1921 if (isspace(oneBefore
)) {
1922 if ((isspace(oneAfter
)) || (oneAfter
== '\0')
1924 && (isspace(twoAfter
) || twoAfter
== '\0'))) {
1934 * UbikQuorumCheck() -- Determine if Ubik has achieved quorum for a specified
1935 * database instance in host's cell.
1937 * RETURN CODES: 1 success, 0 failure (st indicates why)
1940 UbikQuorumCheck(cfg_host_p cfg_host
, const char *dbInstance
, short *hasQuorum
,
1944 afs_status_t tst2
, tst
= 0;
1949 if (!bos_HostGetBegin(cfg_host
->bosHandle
, &dbIter
, &tst2
)) {
1952 /* iterate over server CellServDb, looking for dbserver sync site */
1953 char dbhostName
[BOS_MAX_NAME_LEN
];
1955 unsigned short dbhostPort
= 0;
1957 int dbhostQueries
= 0;
1959 if (!strcmp(dbInstance
, KASERVER_BOSNAME
)) {
1960 dbhostPort
= AFSCONF_KAUTHPORT
;
1961 } else if (!strcmp(dbInstance
, PTSERVER_BOSNAME
)) {
1962 dbhostPort
= AFSCONF_PROTPORT
;
1963 } else if (!strcmp(dbInstance
, VLSERVER_BOSNAME
)) {
1964 dbhostPort
= AFSCONF_VLDBPORT
;
1965 } else if (!strcmp(dbInstance
, BUSERVER_BOSNAME
)) {
1966 dbhostPort
= AFSCONF_BUDBPORT
;
1969 while (!dbhostDone
) {
1970 if (!bos_HostGetNext(dbIter
, dbhostName
, &tst2
)) {
1971 /* no more entries (or failure) */
1972 if (tst2
== ADMITERATORDONE
) {
1973 if (dbhostQueries
== 0) {
1974 /* consider quorum to have been achieved when no
1975 * database servers in cell; otherwise higher-level
1976 * functions will timeout and fail.
1986 if (!util_AdminServerAddressGetFromName
1987 (dbhostName
, &dbhostAddr
, &tst2
)) {
1991 short isSyncSite
= 0;
1992 short isWriteReady
= 0;
1994 /* ignore errors fetching Ubik vote status; there might be
1995 * an unreachable dbserver yet a reachable sync site.
1999 if (UbikVoteStatusFetch
2000 (dbhostAddr
, dbhostPort
, &isSyncSite
, &isWriteReady
,
2002 /* have quorum if is sync site AND is ready for updates */
2013 if (!bos_HostGetDone(dbIter
, &tst2
)) {
2019 /* indicate failure */
2030 * UbikVoteStatusFetch() -- Fetch Ubik vote status parameters of interest from
2031 * specified server and port.
2033 * RETURN CODES: 1 success, 0 failure (st indicates why)
2036 UbikVoteStatusFetch(int serverAddr
, unsigned short serverPort
,
2037 short *isSyncSite
, short *isWriteReady
, afs_status_p st
)
2040 afs_status_t tst
= 0;
2041 struct rx_securityClass
*nullSecurity
;
2042 struct rx_connection
*serverConn
;
2044 nullSecurity
= rxnull_NewClientSecurityObject(); /* never fails */
2047 rx_GetCachedConnection(htonl(serverAddr
), htons(serverPort
),
2048 VOTE_SERVICE_ID
, nullSecurity
, 0)) == NULL
) {
2049 tst
= ADMCFGUBIKVOTENOCONNECTION
;
2052 struct ubik_debug udebugInfo
;
2054 if ((rpcCode
= VOTE_Debug(serverConn
, &udebugInfo
)) == 0) {
2055 /* talking to a 3.5 or later server */
2056 *isSyncSite
= (udebugInfo
.amSyncSite
? 1 : 0);
2060 /* as of 3.5 the database is writable if "labeled" or if all
2061 * prior recovery states have been achieved; see defect 9477.
2063 if (((udebugInfo
.recoveryState
& UBIK_RECLABELDB
))
2064 || ((udebugInfo
.recoveryState
& UBIK_RECSYNCSITE
)
2065 && (udebugInfo
.recoveryState
& UBIK_RECFOUNDDB
)
2066 && (udebugInfo
.recoveryState
& UBIK_RECHAVEDB
))) {
2071 } else if (rpcCode
== RXGEN_OPCODE
) {
2072 /* talking to old (pre 3.5) server */
2073 struct ubik_debug_old udebugInfo
;
2075 if ((rpcCode
= VOTE_DebugOld(serverConn
, &udebugInfo
)) == 0) {
2076 *isSyncSite
= (udebugInfo
.amSyncSite
? 1 : 0);
2080 /* pre 3.5 the database is writable only if "labeled" */
2081 if (udebugInfo
.recoveryState
& UBIK_RECLABELDB
) {
2088 (void)rx_ReleaseCachedConnection(serverConn
);
2094 /* indicate failure */