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 #include <afsconfig.h>
11 #include <afs/param.h>
13 #include <afs/procmgmt.h>
18 #ifdef IGNORE_SOME_GCC_WARNINGS
19 # pragma GCC diagnostic warning "-Wimplicit-function-declaration"
23 #include <WINNT/afsevent.h>
29 #include <rx/rx_globals.h>
33 #include <afs/afsint.h>
34 #include <afs/prs_fs.h>
36 #include <afs/vlserver.h>
39 #include <afs/afsutil.h>
40 #include <afs/cellconfig.h>
42 #include <afs/volser.h>
44 #include <afs/com_err.h>
46 #include <afs/tcdata.h>
47 #include <afs/bubasics.h>
48 #include <afs/budb_errs.h>
49 #include <afs/budb_client.h>
50 #include <afs/bucoord_prototypes.h>
52 #include <afs/kautils.h>
55 #include "error_macros.h"
57 #include "butc_xbsa.h"
58 #include "butc_prototypes.h"
60 #define N_SECURITY_OBJECTS 3
61 #define ERRCODE_RANGE 8 /* from error_table.h */
63 #define TE_PREFIX "TE"
64 #define TL_PREFIX "TL"
65 #define CFG_PREFIX "CFG"
67 struct ubik_client *cstruct;
68 FILE *logIO, *ErrorlogIO, *centralLogIO, *lastLogIO;
69 char lFile[AFSDIR_PATH_MAX];
71 char ErrorlogFile[256];
72 char lastLogFile[256];
73 char eFile[AFSDIR_PATH_MAX];
74 char tapeConfigFile[AFSDIR_PATH_MAX];
75 char pFile[AFSDIR_PATH_MAX];
77 struct tapeConfig globalTapeConfig;
78 struct deviceSyncNode *deviceLatch;
79 char globalCellName[64];
80 char *whoami = "butc";
82 /* GLOBAL CONFIGURATION PARAMETERS */
98 #define MINGROUPID 0x1
99 #define MAXGROUPID 0x7FFFFFFF
100 afs_int32 statusSize;
102 #define MAXSTATUS 0x7fffffff
103 afs_int32 BufferSize; /* Size in B stored for data */
104 char *centralLogFile;
105 afs_int32 lastLog; /* Log last pass info */
108 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
109 afs_uint32 SHostAddrs[ADDRSPERSITE];
111 /* dummy routine for the audit work. It should do nothing since audits */
112 /* occur at the server level and bos is not a server. */
126 while ((tc = *anum)) {
127 if (tc < '0' || tc > '9')
137 * Convert a string into an afs_int32.
138 * Returned afs_int32 is in Bytes, Kb, Mb, Gb, or Tb. Based on crunit char.
139 * This routine only converts unsigned float values.
140 * The returned value is a whole number.
142 * numstring - text string to be converted.
143 * crunit - value returned in 'B', 'K', 'M', 'G', 'T'.
144 * ' ' or NULL ==> 'B' (bytes).
146 * number - returned value in requested crunit - rounded
147 * to nearest whole number.
150 * -1 - error in conversion
152 * should deal with signed numbers. Should signal error if no digits
156 atocl(char *numstring, char crunit, afs_int32 *number)
165 /* Determine which units to report in */
199 sscanf(numstring, "%f%c%s", &total, &cunit, rest);
200 if ((count > 2) || (count <= 0))
203 cunit = 'B'; /* bytes */
237 /* Go to correct unit */
238 for (; units < runits; units += 3)
240 for (; units > runits; units -= 3)
243 total += 0.5; /* Round up */
244 if ((total > 0x7fffffff) || (total < 0)) /* Don't go over 2G */
251 /* replace last two ocurrences of / by _ */
254 stringReplace(char *name)
259 pos = strrchr(name, '/');
262 pos = strrchr(name, '/');
264 strcat(name, buffer);
270 stringNowReplace(char *logFile, char *deviceName)
273 char storeDevice[256];
274 int mvFlag = 0, devPrefLen;
276 char devPrefix[] = "\\\\.";
278 char devPrefix[] = "/dev";
281 devPrefLen = strlen(devPrefix);
282 strcpy(storeDevice, deviceName);
283 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
284 deviceName += devPrefLen;
287 while ((pos = strchr(deviceName, devPrefix[0]))) /* look for / or \ */
289 strcat(logFile, deviceName);
290 /* now put back deviceName to the way it was */
292 deviceName -= devPrefLen;
294 strcpy(deviceName, storeDevice);
301 * get the configuration information for a particular tape device
302 * as specified by the portoffset
304 * filename - full pathname of file containing the tape device
305 * configuration information
306 * config - for return results
307 * portOffset - for which configuration is required
309 * logging not available when this routine is called
310 * caller return value checks
312 * 0 => Found entry with same port, return info in config.
313 * -1 => Error encountered trying to read the file.
314 * 1 => Desired entry does not exist or file does not exist.
319 GetDeviceConfig(char *filename, struct tapeConfig *config, afs_int32 portOffset)
323 char devName[LINESIZE], tcapacity[LINESIZE], tfmsize[LINESIZE],
328 afs_int32 code = 0, count;
330 /* Initialize the config struct */
331 config->capacity = 0;
332 config->fileMarkSize = 0;
333 config->portOffset = portOffset;
334 strcpy(config->device, "");
336 devFile = fopen(filename, "r");
340 fprintf(stderr, "Error %d: Can't open %s\n", errno, filename);
344 while (fgets(line, LINESIZE - 1, devFile)) {
346 sscanf(line, "%s %s %s %u%s\n", tcapacity, tfmsize, devName,
349 if (count == 4 || count == 5) {
350 if (atocl(tcapacity, 'K', &capacity)) {
352 "tapeconfig: Tape capacity parse error in: %s\n",
356 if (atocl(tfmsize, 'B', &fmSize)) {
358 "tapeconfig: File-mark size parse error in: %s\n",
363 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
364 if (count == 2 || count == 3) {
365 capacity = 0x7fffffff;
368 fprintf(stderr, "tapeconfig: Parse error in: %s\n", line);
373 if ((aport < 0) || (aport > BC_MAXPORTOFFSET)) {
374 fprintf(stderr, "tapeconfig: Port offset parse error in: %s\n",
379 if (aport != portOffset)
383 fprintf(stderr, "Invalid file mark size, %d, in: %s\n", fmSize,
388 config->capacity = capacity;
389 config->fileMarkSize = fmSize;
390 config->portOffset = aport;
391 strncpy(config->device, devName, 100);
396 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
408 GetConfigParams(char *filename, afs_int32 port)
412 char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
416 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
417 dump_namecheck = 1; /* check tape name on dumps */
418 queryoperator = 1; /* can question operator */
419 autoQuery = 1; /* prompt for first tape */
420 isafile = 0; /* Do not dump to a file */
421 opencallout = NULL; /* open callout routine */
422 closecallout = NULL; /* close callout routine */
423 tapemounted = 0; /* tape is not mounted */
425 BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
426 dumpRestAuthnLevel = rpc_c_protect_level_default;
427 xbsaObjectOwner = NULL; /* bsaObjectOwner */
428 appObjectOwner = NULL; /* appObjectOwner */
429 adsmServerName = NULL; /* TSM server name - same as ADSM */
430 xbsaSecToken = NULL; /* XBSA sercurity token */
431 xbsalGName = NULL; /* XBSA IGName */
433 BufferSize = BUTM_BLOCKSIZE;
435 centralLogFile = NULL; /* Log for all butcs */
436 centralLogIO = 0; /* Log for all butcs */
437 statusSize = 0; /* size before status message */
438 maxpass = PASSESDFLT; /* dump passes */
439 lastLog = 0; /* separate log for last pass */
440 lastLogIO = 0; /* separate log for last pass */
441 groupId = 0; /* Group id for multiple dumps */
443 /* Try opening the CFG_<port> file */
444 sprintf(paramFile, "%s_%d", filename, port);
445 devFile = fopen(paramFile, "r");
447 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
448 sprintf(logFile, "%s_%d", lFile, port);
449 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
450 sprintf(ErrorlogFile, "%s_%d", eFile, port);
451 } else if (CONF_XBSA) {
452 /* If configured as XBSA, a configuration file CFG_<port> must exist */
453 printf("Cannot open configuration file %s", paramFile);
456 /* Try the CFG_<device> name as the device file */
457 strcpy(paramFile, filename);
458 stringNowReplace(paramFile, globalTapeConfig.device);
459 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
460 strcpy(logFile, lFile);
461 stringNowReplace(logFile, globalTapeConfig.device);
462 strcpy(lastLogFile, lFile);
463 stringNowReplace(lastLogFile, globalTapeConfig.device);
464 strcat(lastLogFile, ".lp");
465 strcpy(ErrorlogFile, eFile);
466 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
468 /* Now open the device file */
469 devFile = fopen(paramFile, "r");
471 ERROR_EXIT(0); /* CFG file doesn't exist for non-XBSA and that's ok */
474 /* Read each line of the Configuration file */
475 while (fgets(line, LINESIZE - 1, devFile)) {
476 cnt = sscanf(line, "%s %s", cmd, value);
479 printf("Bad line in %s: %s\n", paramFile, line);
483 for (cnt = 0; cnt < strlen(cmd); cnt++)
484 if (islower(cmd[cnt]))
485 cmd[cnt] = toupper(cmd[cnt]);
487 if (!strcmp(cmd, "NAME_CHECK")) {
490 ("Warning: The %s parameter is ignored with a Backup Service\n",
495 for (cnt = 0; cnt < strlen(value); cnt++)
496 if (islower(value[cnt]))
497 value[cnt] = toupper(value[cnt]);
499 if (!strcmp(value, "NO")) {
500 printf("Dump tape name check is disabled\n");
503 printf("Dump tape name check is enabled\n");
508 else if (!strcmp(cmd, "MOUNT")) {
511 ("Warning: The %s parameter is ignored with a Backup Service\n",
516 opencallout = strdup(value);
517 printf("Tape mount callout routine is %s\n", opencallout);
520 else if (!strcmp(cmd, "UNMOUNT")) {
523 ("Warning: The %s parameter is ignored with a Backup Service\n",
528 closecallout = strdup(value);
529 printf("Tape unmount callout routine is %s\n", closecallout);
532 else if (!strcmp(cmd, "ASK")) {
533 for (cnt = 0; cnt < strlen(value); cnt++)
534 if (islower(value[cnt]))
535 value[cnt] = toupper(value[cnt]);
537 if (!strcmp(value, "NO")) {
538 printf("Operator queries are disabled\n");
541 printf("Operator queries are enabled\n");
546 else if (!strcmp(cmd, "FILE")) {
549 ("Warning: The %s parameter is ignored with a Backup Service\n",
554 for (cnt = 0; cnt < strlen(value); cnt++)
555 if (islower(value[cnt]))
556 value[cnt] = toupper(value[cnt]);
558 if (!strcmp(value, "YES")) {
559 printf("Will dump to a file\n");
562 printf("Will not dump to a file\n");
567 else if (!strcmp(cmd, "AUTOQUERY")) {
570 ("Warning: The %s parameter is ignored with a Backup Service\n",
575 for (cnt = 0; cnt < strlen(value); cnt++)
576 if (islower(value[cnt]))
577 value[cnt] = toupper(value[cnt]);
579 if (!strcmp(value, "NO")) {
580 printf("Auto query is disabled\n");
583 printf("Auto query is enabled\n");
588 else if (!strcmp(cmd, "BUFFERSIZE")) {
590 afs_int32 tapeblocks;
593 if (atocl(value, 'K', &size)) {
594 fprintf(stderr, "BUFFERSIZE parse error\n");
598 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
599 * determine BufferSize needed for that many tapeblocks.
601 tapeblocks = size / 16;
604 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16));
605 BufferSize = tapeblocks * BUTM_BLOCKSIZE;
608 if (atocl(value, 'B', &size)) {
609 fprintf(stderr, "BUFFERSIZE parse error\n");
612 if (size < XBSAMINBUFFER)
613 size = XBSAMINBUFFER;
614 if (size > XBSAMAXBUFFER)
615 size = XBSAMAXBUFFER;
616 printf("XBSA buffer size is %u Bytes\n", size);
622 /* All the xbsa spacific parameters */
623 else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE")
624 || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD")
625 || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) {
626 printf("This binary does not have XBSA support\n");
630 else if (!strcmp(cmd, "TYPE")) { /* required for XBSA */
633 ("Warning: The %s parameter is ignored with a tape drive\n",
638 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
639 if (islower(value[cnt]))
640 value[cnt] = toupper(value[cnt]);
642 if (strcmp(value, "TSM") == 0) {
643 xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */
645 printf("Configuration file error, %s %s is not recognized\n",
647 xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
649 printf("XBSA type is %s\n",
651 XBSA_SERVER_TYPE_UNKNOWN) ? "Unknown" : value));
654 else if (!strcmp(cmd, "NODE")) {
657 ("Warning: The %s parameter is ignored with a tape drive\n",
661 xbsaObjectOwner = strdup(value);
662 printf("XBSA node is %s\n", xbsaObjectOwner);
665 else if (!strcmp(cmd, "SERVER")) { /* required for XBSA */
668 ("Warning: The %s parameter is ignored with a tape drive\n",
672 adsmServerName = strdup(value);
673 printf("XBSA server is %s\n", adsmServerName);
676 else if (!strcmp(cmd, "PASSWORD")) { /* This or PASSFILE required for XBSA */
679 ("Warning: The %s parameter is ignored with a tape drive\n",
685 ("Warning: The %s parameter is ignored. Already read password\n",
690 xbsaSecToken = strdup(value);
691 printf("XBSA Password has been read\n");
694 else if (!strcmp(cmd, "PASSFILE")) { /* This or PASSWORD required for XBSA */
698 ("Warning: The %s parameter is ignored with a tape drive\n",
704 ("Warning: The %s parameter is ignored. Already read password\n",
709 pwdFile = fopen(value, "r");
712 ("Configuration file error, cannot open password file %s\n",
716 xbsaSecToken = malloc(LINESIZE);
717 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
719 ("Configuration file error, cannot read password file %s\n",
723 printf("XBSA password retrieved from password file\n");
726 else if (!strcmp(cmd, "MGMTCLASS")) { /* XBSA */
729 ("Warning: The %s parameter is ignored with a tape drive\n",
733 xbsalGName = strdup(value);
734 printf("XBSA management class is %s\n", xbsalGName);
738 else if (!strcmp(cmd, "MAXPASS")) {
739 maxpass = SafeATOL(value);
740 if (maxpass < PASSESMIN)
742 if (maxpass > PASSESMAX)
744 printf("MAXPASS is %d\n", maxpass);
747 else if (!strcmp(cmd, "GROUPID")) {
748 groupId = SafeATOL(value);
749 if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
750 printf("Configuration file error, %s %s is invalid\n", cmd,
754 printf("Group Id is %d\n", groupId);
757 else if (!strcmp(cmd, "LASTLOG")) {
758 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
759 if (islower(value[cnt]))
760 value[cnt] = toupper(value[cnt]);
762 lastLog = (strcmp(value, "YES") == 0);
763 printf("Will %sgenerate a last log\n", (lastLog ? "" : "not "));
766 else if (!strcmp(cmd, "CENTRALLOG")) {
767 centralLogFile = strdup(value);
768 printf("Central log file is %s\n", centralLogFile);
771 else if (!strcmp(cmd, "STATUS")) {
772 if (atocl(value, 'B', &statusSize)) {
773 fprintf(stderr, "STATUS parse error\n");
776 if (statusSize < MINSTATUS)
777 statusSize = MINSTATUS;
778 if (statusSize > MAXSTATUS)
779 statusSize = MAXSTATUS;
783 printf("Warning: Unrecognized configuration parameter: %s", line);
788 /* Statussize is in bytes and requires that BufferSize be set first */
789 statusSize *= BufferSize;
791 statusSize = 0x7fffffff; /*max size */
792 printf("Status every %ld Bytes\n", afs_printable_int32_ld(statusSize));
799 /* If the butc is configured as XBSA, check for required parameters */
801 if (!code && CONF_XBSA) {
802 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
804 ("Configuration file error, the TYPE parameter must be specified, or\n");
805 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
809 if (!adsmServerName) {
811 ("Configuration file error, the SERVER parameter must be specified\n");
816 ("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
828 xbsa_Finalize(&butxInfo);
834 WorkerBee(struct cmd_syndesc *as, void *arock)
837 struct rx_securityClass *(securityObjects[1]);
838 struct rx_service *service;
842 /*process arguments */
843 afs_int32 portOffset = 0;
844 #ifdef AFS_PTHREAD_ENV
845 pthread_t dbWatcherPid;
846 pthread_attr_t tattr;
849 PROCESS dbWatcherPid;
851 afs_uint32 host = htonl(INADDR_ANY);
855 /*initialize the error tables */
856 initialize_KA_error_table();
857 initialize_RXK_error_table();
858 initialize_KTC_error_table();
859 initialize_ACFG_error_table();
860 initialize_CMD_error_table();
861 initialize_VL_error_table();
862 initialize_BUTM_error_table();
863 initialize_BUTC_error_table();
865 initialize_BUTX_error_table();
867 initialize_VOLS_error_table();
868 initialize_BUDB_error_table();
869 initialize_BUCD_error_table();
871 if (as->parms[0].items) {
872 portOffset = SafeATOL(as->parms[0].items->data);
873 if (portOffset == -1) {
874 fprintf(stderr, "Illegal port offset '%s'\n",
875 as->parms[0].items->data);
877 } else if (portOffset > BC_MAXPORTOFFSET) {
878 fprintf(stderr, "%u exceeds max port offset %u\n", portOffset,
884 xbsaType = XBSA_SERVER_TYPE_NONE; /* default */
885 if (as->parms[3].items) { /* -device */
886 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
887 globalTapeConfig.fileMarkSize = 0;
888 globalTapeConfig.portOffset = portOffset;
889 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
890 xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */
892 /* Search for an entry in tapeconfig file */
893 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
895 fprintf(stderr, "Problem in reading config file %s\n",
899 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
900 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
903 ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE);
906 if (as->parms[6].items) { /* -restoretofile */
907 restoretofile = strdup(as->parms[6].items->data);
908 printf("Restore to file '%s'\n", restoretofile);
911 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
912 * the exact xbsaType within the call (won't be unknown) - double check.
914 code = GetConfigParams(pFile, portOffset);
918 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
920 ("\nConfiguration file error, the TYPE parameter must be specified, or\n");
921 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
926 /* Not compiled for XBSA code so we can't support it */
928 printf("\nNo entry found in %s for port %d\n", tapeConfigFile,
930 printf("This binary does not have XBSA support\n");
935 /* Open the log files. The pathnames were set in GetConfigParams() */
936 logIO = fopen(logFile, "a");
938 fprintf(stderr, "Failed to open %s\n", logFile);
941 ErrorlogIO = fopen(ErrorlogFile, "a");
943 fprintf(stderr, "Failed to open %s\n", ErrorlogFile);
947 lastLogIO = fopen(lastLogFile, "a");
949 fprintf(stderr, "Failed to open %s\n", lastLogFile);
953 if (centralLogFile) {
957 char path[AFSDIR_PATH_MAX];
960 statcode = stat(centralLogFile, &sbuf);
961 centralLogIO = fopen(centralLogFile, "a");
963 fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile,
968 /* Make sure it is not in AFS, has to have been created first */
969 if (!realpath(centralLogFile, path)) {
971 "Warning: can't determine real path of '%s' (%d)\n",
972 centralLogFile, errno);
974 if (strncmp(path, "/afs/", 5) == 0) {
975 fprintf(stderr, "The central log '%s' should not be in AFS\n",
982 /* Write header if created it */
985 "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
987 "----- ------------------- ------------------- -------- ---------\n";
988 /* File didn't exist before so write the header lines */
989 fwrite(h1, strlen(h1), 1, centralLogIO);
990 fwrite(h2, strlen(h2), 1, centralLogIO);
991 fflush(centralLogIO);
995 if (as->parms[1].items) {
996 debugLevel = SafeATOL(as->parms[1].items->data);
997 if (debugLevel == -1) {
998 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
1003 /* Setup XBSA library interface */
1006 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
1007 if (rc != XBSA_SUCCESS) {
1008 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
1012 forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */
1014 printf("Force XBSA multiple server support\n");
1016 rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName);
1017 if (rc != XBSA_SUCCESS)
1019 (void)signal(SIGINT, xbsa_shutdown);
1020 (void)signal(SIGHUP, xbsa_shutdown);
1025 if (as->parms[2].items)
1026 strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
1030 if (as->parms[4].items)
1033 localauth = (as->parms[5].items ? 1 : 0);
1034 rxBind = (as->parms[8].items ? 1 : 0);
1038 if (AFSDIR_SERVER_NETRESTRICT_FILEPATH ||
1039 AFSDIR_SERVER_NETINFO_FILEPATH) {
1041 ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL,
1042 ADDRSPERSITE, reason,
1043 AFSDIR_SERVER_NETINFO_FILEPATH,
1044 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
1047 ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
1050 host = SHostAddrs[0];
1053 code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset));
1055 TapeLog(0, 0, code, 0, "rx init failed on port %u\n",
1056 BC_TAPEPORT + portOffset);
1059 rx_SetRxDeadTime(150);
1061 /* Establish connection with the vldb server */
1062 code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires);
1064 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1068 strcpy(globalCellName, cellName);
1070 /*initialize the dumpNode list */
1071 InitNodeList(portOffset);
1073 deviceLatch = malloc(sizeof(struct deviceSyncNode));
1074 Lock_Init(&(deviceLatch->lock));
1075 deviceLatch->flags = 0;
1077 /* initialize database support, volume support, and logs */
1079 /* Create a single security object, in this case the null security
1080 * object, for unauthenticated connections, which will be used to control
1081 * security on connections made to this server
1084 securityObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject();
1085 if (!securityObjects[RX_SECIDX_NULL]) {
1086 TLog(0, "rxnull_NewServerSecurityObject");
1091 rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 1, TC_ExecuteRequest);
1093 TLog(0, "rx_NewService");
1096 rx_SetMaxProcs(service, 4);
1098 /* Establish connection to the backup database */
1099 code = udbClientInit(0, localauth, cellName);
1101 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1104 /* This call is here to verify that we are authentiated.
1105 * The call does nothing and will return BUDB_NOTPERMITTED
1106 * if we don't belong.
1108 code = bcdb_deleteDump(0, 0, 0, 0);
1109 if (code == BUDB_NOTPERMITTED) {
1110 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1115 #ifdef AFS_PTHREAD_ENV
1116 code = pthread_attr_init(&tattr);
1118 TapeLog(0, 0, code, 0,
1119 "Can't pthread_attr_init database monitor task");
1122 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1124 TapeLog(0, 0, code, 0,
1125 "Can't pthread_attr_setdetachstate database monitor task");
1129 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1130 AFS_SIGSET_RESTORE();
1133 LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2,
1134 "dbWatcher", &dbWatcherPid);
1137 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1141 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1142 portOffset, debugLevel);
1143 TLog(0, "Token expires: %s\n", cTIME(&tokenExpires));
1145 rx_StartServer(1); /* Donate this process to the server process pool */
1146 TLog(0, "Error: StartServer returned");
1150 #ifndef AFS_NT40_ENV
1151 #include "AFS_component_version_number.c"
1155 main(int argc, char **argv)
1157 struct cmd_syndesc *ts;
1158 struct cmd_item *ti;
1160 #ifdef AFS_AIX32_ENV
1162 * The following signal action for AIX is necessary so that in case of a
1163 * crash (i.e. core is generated) we can include the user's data section
1164 * in the core dump. Unfortunately, by default, only a partial core is
1165 * generated which, in many cases, isn't too useful.
1167 struct sigaction nsa;
1169 sigemptyset(&nsa.sa_mask);
1170 nsa.sa_handler = SIG_DFL;
1171 nsa.sa_flags = SA_FULLDUMP;
1172 sigaction(SIGSEGV, &nsa, NULL);
1173 sigaction(SIGABRT, &nsa, NULL);
1178 ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, 0, "tape coordinator");
1179 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset");
1180 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2");
1181 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1182 cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1183 "tape device path");
1184 cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL,
1185 "do not query operator for first tape");
1186 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL,
1187 "create tickets from KeyFile");
1188 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1189 "file to restore to");
1190 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL | CMD_HIDE),
1191 "Force multiple XBSA server support");
1192 cmd_AddParm(ts, "-rxbind", CMD_FLAG, CMD_OPTIONAL,
1195 /* Initialize dirpaths */
1196 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1198 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1200 fprintf(stderr, "Unable to obtain AFS server directory.\n");
1204 /* setup the file paths */
1205 strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1206 TE_PREFIX, (char *)NULL);
1207 strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1208 TL_PREFIX, (char *)NULL);
1209 strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1210 CFG_PREFIX, (char *)NULL);
1211 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH);
1213 /* special case "no args" case since cmd_dispatch gives help message
1217 ts = calloc(1, sizeof(struct cmd_syndesc));
1219 ti = malloc(sizeof(struct cmd_item));
1222 ts->parms[0].items = ti;
1223 ti = malloc(sizeof(struct cmd_item));
1226 ts->parms[1].items = ti;
1227 ts->parms[2].items = NULL;
1228 ts->parms[3].items = NULL;
1229 ts->parms[4].items = NULL;
1230 ts->parms[5].items = NULL;
1231 return WorkerBee(ts, NULL);
1233 return cmd_Dispatch(argc, argv);