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>
16 #include <sys/types.h>
20 #include <WINNT/afsevent.h>
22 #include <netinet/in.h>
25 #include <afs/procmgmt.h>
27 #include <afs/afsint.h>
29 #ifdef AFS_PTHREAD_ENV
32 #include <afs/assert.h>
34 #include <afs/prs_fs.h>
37 #include <afs/vlserver.h>
40 #include <afs/afsutil.h>
42 #include <rx/rx_globals.h>
45 #include <afs/cellconfig.h>
47 #include <afs/volser.h>
49 #include <afs/com_err.h>
52 #include <afs/tcdata.h>
53 #include <afs/bubasics.h>
55 #include "error_macros.h"
56 #include <afs/budb_errs.h>
58 #include "butc_xbsa.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 extern void TC_ExecuteRequest();
69 extern int dbWatcher();
70 FILE *logIO, *ErrorlogIO, *centralLogIO, *lastLogIO;
71 char lFile[AFSDIR_PATH_MAX];
73 char ErrorlogFile[256];
74 char lastLogFile[256];
75 char eFile[AFSDIR_PATH_MAX];
76 char tapeConfigFile[AFSDIR_PATH_MAX];
77 char pFile[AFSDIR_PATH_MAX];
79 struct tapeConfig globalTapeConfig;
80 struct deviceSyncNode *deviceLatch;
81 char globalCellName[64];
82 char *whoami = "butc";
84 /* GLOBAL CONFIGURATION PARAMETERS */
95 /* XBSA Global Parameters */
98 struct butx_transactionInfo butxInfo;
100 #define rpc_c_protect_level_default 0
101 afs_uint32 dumpRestAuthnLevel = rpc_c_protect_level_default;
102 char *xbsaObjectOwner;
103 char *appObjectOwner;
104 char *adsmServerName;
114 #define MINGROUPID 0x1
115 #define MAXGROUPID 0x7FFFFFFF
116 afs_int32 statusSize;
118 #define MAXSTATUS 0x7fffffff
119 afs_int32 BufferSize; /* Size in B stored for data */
120 char *centralLogFile;
121 afs_int32 lastLog; /* Log last pass info */
123 /* dummy routine for the audit work. It should do nothing since audits */
124 /* occur at the server level and bos is not a server. */
134 register afs_int32 total;
139 if (tc < '0' || tc > '9')
149 * Convert a string into an afs_int32.
150 * Returned afs_int32 is in Bytes, Kb, Mb, Gb, or Tb. Based on crunit char.
151 * This routine only converts unsigned float values.
152 * The returned value is a whole number.
154 * numstring - text string to be converted.
155 * crunit - value returned in 'B', 'K', 'M', 'G', 'T'.
156 * ' ' or NULL ==> 'B' (bytes).
158 * number - returned value in requested crunit - rounded
159 * to nearest whole number.
162 * -1 - error in conversion
164 * should deal with signed numbers. Should signal error if no digits
167 atocl(numstring, crunit, number)
169 char crunit; /* Units to report number in */
179 /* Determine which units to report in */
213 sscanf(numstring, "%f%c%s", (unsigned char *)&total, &cunit, rest);
214 if ((count > 2) || (count <= 0))
217 cunit = 'B'; /* bytes */
251 /* Go to correct unit */
252 for (; units < runits; units += 3)
254 for (; units > runits; units -= 3)
257 total += 0.5; /* Round up */
258 if ((total > 0x7fffffff) || (total < 0)) /* Don't go over 2G */
265 /* replace last two ocurrences of / by _ */
273 pos = strrchr(name, '/');
276 pos = strrchr(name, '/');
278 strcat(name, buffer);
283 stringNowReplace(logFile, deviceName)
284 char *logFile, *deviceName;
288 char storeDevice[256];
289 int mvFlag = 0, devPrefLen;
291 char devPrefix[] = "\\\\.";
293 char devPrefix[] = "/dev";
296 devPrefLen = strlen(devPrefix);
297 strcpy(storeDevice, deviceName);
298 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
299 deviceName += devPrefLen;
302 while (pos = strchr(deviceName, devPrefix[0])) /* look for / or \ */
304 strcat(logFile, deviceName);
305 /* now put back deviceName to the way it was */
308 deviceName -= devPrefLen;
310 strcpy(deviceName, storeDevice);
317 * get the configuration information for a particular tape device
318 * as specified by the portoffset
320 * filename - full pathname of file containing the tape device
321 * configuration information
322 * config - for return results
323 * portOffset - for which configuration is required
325 * logging not available when this routine is called
326 * caller return value checks
328 * 0 => Found entry with same port, return info in config.
329 * -1 => Error encountered trying to read the file.
330 * 1 => Desired entry does not exist or file does not exist.
335 GetDeviceConfig(filename, config, portOffset)
337 struct tapeConfig *config;
338 afs_int32 portOffset;
342 char devName[LINESIZE], tcapacity[LINESIZE], tfmsize[LINESIZE],
347 afs_int32 code = 0, count;
349 /* Initialize the config struct */
350 config->capacity = 0;
351 config->fileMarkSize = 0;
352 config->portOffset = portOffset;
353 strcpy(config->device, "");
355 devFile = fopen(filename, "r");
359 fprintf(stderr, "Error %d: Can't open %s\n", errno, filename);
363 while (fgets(line, LINESIZE - 1, devFile)) {
365 sscanf(line, "%s %s %s %u%s\n", tcapacity, tfmsize, devName,
368 if (count == 4 || count == 5) {
369 if (atocl(tcapacity, 'K', &capacity)) {
371 "tapeconfig: Tape capacity parse error in: %s\n",
375 if (atocl(tfmsize, 'B', &fmSize)) {
377 "tapeconfig: File-mark size parse error in: %s\n",
382 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
383 if (count == 2 || count == 3) {
384 capacity = 0x7fffffff;
387 fprintf(stderr, "tapeconfig: Parse error in: %s\n", line);
392 if ((aport < 0) || (aport > BC_MAXPORTOFFSET)) {
393 fprintf(stderr, "tapeconfig: Port offset parse error in: %s\n",
398 if (aport != portOffset)
402 fprintf(stderr, "Invalid file mark size, %d, in: %s\n", fmSize,
407 config->capacity = capacity;
408 config->fileMarkSize = fmSize;
409 config->portOffset = aport;
410 strncpy(config->device, devName, 100);
415 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
427 GetConfigParams(filename, port)
433 char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
437 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
438 dump_namecheck = 1; /* check tape name on dumps */
439 queryoperator = 1; /* can question operator */
440 autoQuery = 1; /* prompt for first tape */
441 isafile = 0; /* Do not dump to a file */
442 opencallout = NULL; /* open callout routine */
443 closecallout = NULL; /* close callout routine */
444 tapemounted = 0; /* tape is not mounted */
446 BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
447 dumpRestAuthnLevel = rpc_c_protect_level_default;
448 xbsaObjectOwner = NULL; /* bsaObjectOwner */
449 appObjectOwner = NULL; /* appObjectOwner */
450 adsmServerName = NULL; /* TSM server name - same as ADSM */
451 xbsaSecToken = NULL; /* XBSA sercurity token */
452 xbsalGName = NULL; /* XBSA IGName */
454 BufferSize = BUTM_BLOCKSIZE;
456 centralLogFile = NULL; /* Log for all butcs */
457 centralLogIO = 0; /* Log for all butcs */
458 statusSize = 0; /* size before status message */
459 maxpass = PASSESDFLT; /* dump passes */
460 lastLog = 0; /* separate log for last pass */
461 lastLogIO = 0; /* separate log for last pass */
462 groupId = 0; /* Group id for multiple dumps */
464 /* Try opening the CFG_<port> file */
465 sprintf(paramFile, "%s_%d", filename, port);
466 devFile = fopen(paramFile, "r");
468 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
469 sprintf(logFile, "%s_%d", lFile, port);
470 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
471 sprintf(ErrorlogFile, "%s_%d", eFile, port);
472 } else if (CONF_XBSA) {
473 /* If configured as XBSA, a configuration file CFG_<port> must exist */
474 printf("Cannot open configuration file %s", paramFile);
477 /* Try the CFG_<device> name as the device file */
478 strcpy(paramFile, filename);
479 stringNowReplace(paramFile, globalTapeConfig.device);
480 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
481 strcpy(logFile, lFile);
482 stringNowReplace(logFile, globalTapeConfig.device);
483 strcpy(lastLogFile, lFile);
484 stringNowReplace(lastLogFile, globalTapeConfig.device);
485 strcat(lastLogFile, ".lp");
486 strcpy(ErrorlogFile, eFile);
487 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
489 /* Now open the device file */
490 devFile = fopen(paramFile, "r");
492 ERROR_EXIT(0); /* CFG file doesn't exist for non-XBSA and that's ok */
495 /* Read each line of the Configuration file */
496 while (fgets(line, LINESIZE - 1, devFile)) {
497 cnt = sscanf(line, "%s %s", cmd, value);
500 printf("Bad line in %s: %s\n", paramFile, line);
504 for (cnt = 0; cnt < strlen(cmd); cnt++)
505 if (islower(cmd[cnt]))
506 cmd[cnt] = toupper(cmd[cnt]);
508 if (!strcmp(cmd, "NAME_CHECK")) {
511 ("Warning: The %s parameter is ignored with a Backup Service\n",
516 for (cnt = 0; cnt < strlen(value); cnt++)
517 if (islower(value[cnt]))
518 value[cnt] = toupper(value[cnt]);
520 if (!strcmp(value, "NO")) {
521 printf("Dump tape name check is disabled\n");
524 printf("Dump tape name check is enabled\n");
529 else if (!strcmp(cmd, "MOUNT")) {
532 ("Warning: The %s parameter is ignored with a Backup Service\n",
537 opencallout = (char *)malloc(strlen(value) + 1);
538 strcpy(opencallout, value);
539 printf("Tape mount callout routine is %s\n", opencallout);
542 else if (!strcmp(cmd, "UNMOUNT")) {
545 ("Warning: The %s parameter is ignored with a Backup Service\n",
550 closecallout = (char *)malloc(strlen(value) + 1);
551 strcpy(closecallout, value);
552 printf("Tape unmount callout routine is %s\n", closecallout);
555 else if (!strcmp(cmd, "ASK")) {
556 for (cnt = 0; cnt < strlen(value); cnt++)
557 if (islower(value[cnt]))
558 value[cnt] = toupper(value[cnt]);
560 if (!strcmp(value, "NO")) {
561 printf("Operator queries are disabled\n");
564 printf("Operator queries are enabled\n");
569 else if (!strcmp(cmd, "FILE")) {
572 ("Warning: The %s parameter is ignored with a Backup Service\n",
577 for (cnt = 0; cnt < strlen(value); cnt++)
578 if (islower(value[cnt]))
579 value[cnt] = toupper(value[cnt]);
581 if (!strcmp(value, "YES")) {
582 printf("Will dump to a file\n");
585 printf("Will not dump to a file\n");
590 else if (!strcmp(cmd, "AUTOQUERY")) {
593 ("Warning: The %s parameter is ignored with a Backup Service\n",
598 for (cnt = 0; cnt < strlen(value); cnt++)
599 if (islower(value[cnt]))
600 value[cnt] = toupper(value[cnt]);
602 if (!strcmp(value, "NO")) {
603 printf("Auto query is disabled\n");
606 printf("Auto query is enabled\n");
611 else if (!strcmp(cmd, "BUFFERSIZE")) {
613 afs_int32 tapeblocks;
616 if (atocl(value, 'K', &size)) {
617 fprintf(stderr, "BUFFERSIZE parse error\n");
621 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
622 * determine BufferSize needed for that many tapeblocks.
624 tapeblocks = size / 16;
627 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16));
628 BufferSize = tapeblocks * BUTM_BLOCKSIZE;
631 if (atocl(value, 'B', &size)) {
632 fprintf(stderr, "BUFFERSIZE parse error\n");
635 if (size < XBSAMINBUFFER)
636 size = XBSAMINBUFFER;
637 if (size > XBSAMAXBUFFER)
638 size = XBSAMAXBUFFER;
639 printf("XBSA buffer size is %u Bytes\n", size);
645 /* All the xbsa spacific parameters */
646 else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE")
647 || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD")
648 || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) {
649 printf("This binary does not have XBSA support\n");
653 else if (!strcmp(cmd, "TYPE")) { /* required for XBSA */
656 ("Warning: The %s parameter is ignored with a tape drive\n",
661 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
662 if (islower(value[cnt]))
663 value[cnt] = toupper(value[cnt]);
665 if (strcmp(value, "TSM") == 0) {
666 xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */
668 printf("Configuration file error, %s %s is not recognized\n",
670 xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
672 printf("XBSA type is %s\n",
674 XBSA_SERVER_TYPE_UNKNOWN) ? "Unknown" : value));
677 else if (!strcmp(cmd, "NODE")) {
680 ("Warning: The %s parameter is ignored with a tape drive\n",
684 xbsaObjectOwner = malloc(strlen(value) + 1);
685 strcpy(xbsaObjectOwner, value);
686 printf("XBSA node is %s\n", xbsaObjectOwner);
689 else if (!strcmp(cmd, "SERVER")) { /* required for XBSA */
692 ("Warning: The %s parameter is ignored with a tape drive\n",
696 adsmServerName = malloc(strlen(value) + 1);
697 strcpy(adsmServerName, value);
698 printf("XBSA server is %s\n", adsmServerName);
701 else if (!strcmp(cmd, "PASSWORD")) { /* This or PASSFILE required for XBSA */
704 ("Warning: The %s parameter is ignored with a tape drive\n",
710 ("Warning: The %s parameter is ignored. Already read password\n",
715 xbsaSecToken = malloc(strlen(value) + 1);
716 strcpy(xbsaSecToken, value);
717 printf("XBSA Password has been read\n");
720 else if (!strcmp(cmd, "PASSFILE")) { /* This or PASSWORD required for XBSA */
724 ("Warning: The %s parameter is ignored with a tape drive\n",
730 ("Warning: The %s parameter is ignored. Already read password\n",
735 pwdFile = fopen(value, "r");
738 ("Configuration file error, cannot open password file %s\n",
742 xbsaSecToken = malloc(LINESIZE);
743 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
745 ("Configuration file error, cannot read password file %s\n",
749 printf("XBSA password retrieved from password file\n");
752 else if (!strcmp(cmd, "MGMTCLASS")) { /* XBSA */
755 ("Warning: The %s parameter is ignored with a tape drive\n",
759 xbsalGName = malloc(strlen(value) + 1);
760 strcpy(xbsalGName, value);
761 printf("XBSA management class is %s\n", xbsalGName);
765 else if (!strcmp(cmd, "MAXPASS")) {
766 maxpass = SafeATOL(value);
767 if (maxpass < PASSESMIN)
769 if (maxpass > PASSESMAX)
771 printf("MAXPASS is %d\n", maxpass);
774 else if (!strcmp(cmd, "GROUPID")) {
775 groupId = SafeATOL(value);
776 if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
777 printf("Configuration file error, %s %s is invalid\n", cmd,
781 printf("Group Id is %d\n", groupId);
784 else if (!strcmp(cmd, "LASTLOG")) {
785 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
786 if (islower(value[cnt]))
787 value[cnt] = toupper(value[cnt]);
789 lastLog = (strcmp(value, "YES") == 0);
790 printf("Will %sgenerate a last log\n", (lastLog ? "" : "not "));
793 else if (!strcmp(cmd, "CENTRALLOG")) {
794 centralLogFile = malloc(strlen(value) + 1);
795 strcpy(centralLogFile, value);
796 printf("Central log file is %s\n", centralLogFile);
799 else if (!strcmp(cmd, "STATUS")) {
800 if (atocl(value, 'B', &statusSize)) {
801 fprintf(stderr, "STATUS parse error\n");
804 if (statusSize < MINSTATUS)
805 statusSize = MINSTATUS;
806 if (statusSize > MAXSTATUS)
807 statusSize = MAXSTATUS;
811 printf("Warning: Unrecognized configuration parameter: %s", line);
816 /* Statussize is in bytes and requires that BufferSize be set first */
817 statusSize *= BufferSize;
819 statusSize = 0x7fffffff; /*max size */
820 printf("Status every %ld Bytes\n", statusSize);
827 /* If the butc is configured as XBSA, check for required parameters */
829 if (!code && CONF_XBSA) {
830 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
832 ("Configuration file error, the TYPE parameter must be specified, or\n");
833 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
837 if (!adsmServerName) {
839 ("Configuration file error, the SERVER parameter must be specified\n");
844 ("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
854 struct cmd_syndesc *as;
857 register afs_int32 code;
858 struct rx_securityClass *(securityObjects[3]);
859 struct rx_service *service;
860 struct ktc_token ttoken;
863 /*process arguments */
864 afs_int32 portOffset = 0;
865 #ifdef AFS_PTHREAD_ENV
866 pthread_t dbWatcherPid;
867 pthread_attr_t tattr;
870 PROCESS dbWatcherPid;
875 /*initialize the error tables */
876 initialize_KA_error_table();
877 initialize_RXK_error_table();
878 initialize_KTC_error_table();
879 initialize_ACFG_error_table();
880 initialize_CMD_error_table();
881 initialize_VL_error_table();
882 initialize_BUTM_error_table();
883 initialize_BUTC_error_table();
885 initialize_BUTX_error_table();
887 initialize_VOLS_error_table();
888 initialize_BUDB_error_table();
889 initialize_BUCD_error_table();
891 if (as->parms[0].items) {
892 portOffset = SafeATOL(as->parms[0].items->data);
893 if (portOffset == -1) {
894 fprintf(stderr, "Illegal port offset '%s'\n",
895 as->parms[0].items->data);
897 } else if (portOffset > BC_MAXPORTOFFSET) {
898 fprintf(stderr, "%u exceeds max port offset %u\n", portOffset,
904 xbsaType = XBSA_SERVER_TYPE_NONE; /* default */
905 if (as->parms[3].items) { /* -device */
906 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
907 globalTapeConfig.fileMarkSize = 0;
908 globalTapeConfig.portOffset = portOffset;
909 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
910 xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */
912 /* Search for an entry in tapeconfig file */
913 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
915 fprintf(stderr, "Problem in reading config file %s\n",
919 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
920 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
923 ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE);
926 if (as->parms[6].items) { /* -restoretofile */
927 int s = strlen(as->parms[6].items->data);
928 restoretofile = malloc(s + 1);
929 strncpy(restoretofile, as->parms[6].items->data, s + 1);
930 printf("Restore to file '%s'\n", restoretofile);
933 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
934 * the exact xbsaType within the call (won't be unknown) - double check.
936 code = GetConfigParams(pFile, portOffset);
940 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
942 ("\nConfiguration file error, the TYPE parameter must be specified, or\n");
943 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
948 /* Not compiled for XBSA code so we can't support it */
950 printf("\nNo entry found in %s for port %d\n", tapeConfigFile,
952 printf("This binary does not have XBSA support\n");
957 /* Open the log files. The pathnames were set in GetConfigParams() */
958 logIO = fopen(logFile, "a");
960 fprintf(stderr, "Failed to open %s\n", logFile);
963 ErrorlogIO = fopen(ErrorlogFile, "a");
965 fprintf(stderr, "Failed to open %s\n", ErrorlogFile);
969 lastLogIO = fopen(lastLogFile, "a");
971 fprintf(stderr, "Failed to open %s\n", lastLogFile);
975 if (centralLogFile) {
979 char path[AFSDIR_PATH_MAX];
981 statcode = stat(centralLogFile, &sbuf);
982 centralLogIO = fopen(centralLogFile, "a");
984 fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile,
989 /* Make sure it is not in AFS, has to have been created first */
990 if (!realpath(centralLogFile, path)) {
992 "Warning: can't determine real path of '%s' (%d)\n",
993 centralLogFile, errno);
995 if (strncmp(path, "/afs/", 5) == 0) {
996 fprintf(stderr, "The central log '%s' should not be in AFS\n",
1003 /* Write header if created it */
1006 "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
1008 "----- ------------------- ------------------- -------- ---------\n";
1009 /* File didn't exist before so write the header lines */
1010 fwrite(h1, strlen(h1), 1, centralLogIO);
1011 fwrite(h2, strlen(h2), 1, centralLogIO);
1012 fflush(centralLogIO);
1016 if (as->parms[1].items) {
1017 debugLevel = SafeATOL(as->parms[1].items->data);
1018 if (debugLevel == -1) {
1019 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
1024 /* Setup XBSA library interface */
1027 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
1028 if (rc != XBSA_SUCCESS) {
1029 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
1033 forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */
1035 printf("Force XBSA multiple server support\n");
1037 rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName);
1038 if (rc != XBSA_SUCCESS)
1044 if (as->parms[2].items)
1045 strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
1049 if (as->parms[4].items)
1052 localauth = (as->parms[5].items ? 1 : 0);
1054 code = rx_Init(htons(BC_TAPEPORT + portOffset));
1056 TapeLog(0, 0, code, 0, "rx init failed on port %u\n",
1057 BC_TAPEPORT + portOffset);
1060 rx_SetRxDeadTime(150);
1062 /* Establish connection with the vldb server */
1063 code = vldbClientInit(0, localauth, cellName, &cstruct, &ttoken);
1065 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1069 strcpy(globalCellName, cellName);
1071 /*initialize the dumpNode list */
1072 InitNodeList(portOffset);
1075 (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode)));
1076 Lock_Init(&(deviceLatch->lock));
1077 deviceLatch->flags = 0;
1079 /* initialize database support, volume support, and logs */
1081 /* Create a single security object, in this case the null security
1082 * object, for unauthenticated connections, which will be used to control
1083 * security on connections made to this server
1086 securityObjects[0] = rxnull_NewServerSecurityObject();
1087 securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */
1088 if (!securityObjects[0]) {
1089 TLog(0, "rxnull_NewServerSecurityObject");
1094 rx_NewService(0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest);
1096 TLog(0, "rx_NewService");
1099 rx_SetMaxProcs(service, 4);
1101 /* Establish connection to the backup database */
1102 code = udbClientInit(0, localauth, cellName);
1104 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1107 /* This call is here to verify that we are authentiated.
1108 * The call does nothing and will return BUDB_NOTPERMITTED
1109 * if we don't belong.
1111 code = bcdb_deleteDump(0, 0, 0, 0);
1112 if (code == BUDB_NOTPERMITTED) {
1113 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1118 #ifdef AFS_PTHREAD_ENV
1119 code = pthread_attr_init(&tattr);
1121 TapeLog(0, 0, code, 0,
1122 "Can't pthread_attr_init database monitor task");
1125 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1127 TapeLog(0, 0, code, 0,
1128 "Can't pthread_attr_setdetachstate database monitor task");
1132 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1133 AFS_SIGSET_RESTORE();
1136 LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2,
1137 "dbWatcher", &dbWatcherPid);
1140 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1144 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1145 portOffset, debugLevel);
1146 TLog(0, "Token expires: %s\n", cTIME(&ttoken.endTime));
1148 rx_StartServer(1); /* Donate this process to the server process pool */
1149 TLog(0, "Error: StartServer returned");
1153 #ifndef AFS_NT40_ENV
1154 #include "AFS_component_version_number.c"
1161 register struct cmd_syndesc *ts;
1162 register struct cmd_item *ti;
1164 #ifdef AFS_AIX32_ENV
1166 * The following signal action for AIX is necessary so that in case of a
1167 * crash (i.e. core is generated) we can include the user's data section
1168 * in the core dump. Unfortunately, by default, only a partial core is
1169 * generated which, in many cases, isn't too useful.
1171 struct sigaction nsa;
1173 sigemptyset(&nsa.sa_mask);
1174 nsa.sa_handler = SIG_DFL;
1175 nsa.sa_flags = SA_FULLDUMP;
1176 sigaction(SIGSEGV, &nsa, NULL);
1177 sigaction(SIGABRT, &nsa, NULL);
1182 ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, "tape coordinator");
1183 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset");
1184 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2");
1185 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1186 cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1187 "tape device path");
1188 cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL,
1189 "do not query operator for first tape");
1190 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL,
1191 "create tickets from KeyFile");
1192 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1193 "file to restore to");
1194 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL | CMD_HIDE),
1195 "Force multiple XBSA server support");
1197 /* Initialize dirpaths */
1198 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1200 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1202 fprintf(stderr, "Unable to obtain AFS server directory.\n");
1206 /* setup the file paths */
1207 strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1209 strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1211 strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1213 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH);
1215 /* special case "no args" case since cmd_dispatch gives help message
1219 ts = (struct cmd_syndesc *)malloc(sizeof(struct cmd_syndesc));
1220 memset(ts, 0, sizeof(*ts));
1222 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1225 ts->parms[0].items = ti;
1226 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1229 ts->parms[1].items = ti;
1230 ts->parms[2].items = (struct cmd_item *)NULL;
1231 ts->parms[3].items = (struct cmd_item *)NULL;
1232 ts->parms[4].items = (struct cmd_item *)NULL;
1233 ts->parms[5].items = (struct cmd_item *)NULL;
1234 return WorkerBee(ts, NULL);
1236 return cmd_Dispatch(argc, argv);