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 _ */
274 pos = strrchr(name, '/');
277 pos = strrchr(name, '/');
279 strcat(name, buffer);
284 stringNowReplace(logFile, deviceName)
285 char *logFile, *deviceName;
289 char storeDevice[256];
290 int mvFlag = 0, devPrefLen;
292 char devPrefix[] = "\\\\.";
294 char devPrefix[] = "/dev";
297 devPrefLen = strlen(devPrefix);
298 strcpy(storeDevice, deviceName);
299 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
300 deviceName += devPrefLen;
303 while (pos = strchr(deviceName, devPrefix[0])) /* look for / or \ */
305 strcat(logFile, deviceName);
306 /* now put back deviceName to the way it was */
309 deviceName -= devPrefLen;
311 strcpy(deviceName, storeDevice);
318 * get the configuration information for a particular tape device
319 * as specified by the portoffset
321 * filename - full pathname of file containing the tape device
322 * configuration information
323 * config - for return results
324 * portOffset - for which configuration is required
326 * logging not available when this routine is called
327 * caller return value checks
329 * 0 => Found entry with same port, return info in config.
330 * -1 => Error encountered trying to read the file.
331 * 1 => Desired entry does not exist or file does not exist.
336 GetDeviceConfig(filename, config, portOffset)
338 struct tapeConfig *config;
339 afs_int32 portOffset;
343 char devName[LINESIZE], tcapacity[LINESIZE], tfmsize[LINESIZE],
348 afs_int32 code = 0, count;
350 /* Initialize the config struct */
351 config->capacity = 0;
352 config->fileMarkSize = 0;
353 config->portOffset = portOffset;
354 strcpy(config->device, "");
356 devFile = fopen(filename, "r");
360 fprintf(stderr, "Error %d: Can't open %s\n", errno, filename);
364 while (fgets(line, LINESIZE - 1, devFile)) {
366 sscanf(line, "%s %s %s %u%s\n", tcapacity, tfmsize, devName,
369 if (count == 4 || count == 5) {
370 if (atocl(tcapacity, 'K', &capacity)) {
372 "tapeconfig: Tape capacity parse error in: %s\n",
376 if (atocl(tfmsize, 'B', &fmSize)) {
378 "tapeconfig: File-mark size parse error in: %s\n",
383 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
384 if (count == 2 || count == 3) {
385 capacity = 0x7fffffff;
388 fprintf(stderr, "tapeconfig: Parse error in: %s\n", line);
393 if ((aport < 0) || (aport > BC_MAXPORTOFFSET)) {
394 fprintf(stderr, "tapeconfig: Port offset parse error in: %s\n",
399 if (aport != portOffset)
403 fprintf(stderr, "Invalid file mark size, %d, in: %s\n", fmSize,
408 config->capacity = capacity;
409 config->fileMarkSize = fmSize;
410 config->portOffset = aport;
411 strncpy(config->device, devName, 100);
416 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
428 GetConfigParams(filename, port)
434 char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
438 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
439 dump_namecheck = 1; /* check tape name on dumps */
440 queryoperator = 1; /* can question operator */
441 autoQuery = 1; /* prompt for first tape */
442 isafile = 0; /* Do not dump to a file */
443 opencallout = NULL; /* open callout routine */
444 closecallout = NULL; /* close callout routine */
445 tapemounted = 0; /* tape is not mounted */
447 BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
448 dumpRestAuthnLevel = rpc_c_protect_level_default;
449 xbsaObjectOwner = NULL; /* bsaObjectOwner */
450 appObjectOwner = NULL; /* appObjectOwner */
451 adsmServerName = NULL; /* TSM server name - same as ADSM */
452 xbsaSecToken = NULL; /* XBSA sercurity token */
453 xbsalGName = NULL; /* XBSA IGName */
455 BufferSize = BUTM_BLOCKSIZE;
457 centralLogFile = NULL; /* Log for all butcs */
458 centralLogIO = 0; /* Log for all butcs */
459 statusSize = 0; /* size before status message */
460 maxpass = PASSESDFLT; /* dump passes */
461 lastLog = 0; /* separate log for last pass */
462 lastLogIO = 0; /* separate log for last pass */
463 groupId = 0; /* Group id for multiple dumps */
465 /* Try opening the CFG_<port> file */
466 sprintf(paramFile, "%s_%d", filename, port);
467 devFile = fopen(paramFile, "r");
469 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
470 sprintf(logFile, "%s_%d", lFile, port);
471 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
472 sprintf(ErrorlogFile, "%s_%d", eFile, port);
473 } else if (CONF_XBSA) {
474 /* If configured as XBSA, a configuration file CFG_<port> must exist */
475 printf("Cannot open configuration file %s", paramFile);
478 /* Try the CFG_<device> name as the device file */
479 strcpy(paramFile, filename);
480 stringNowReplace(paramFile, globalTapeConfig.device);
481 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
482 strcpy(logFile, lFile);
483 stringNowReplace(logFile, globalTapeConfig.device);
484 strcpy(lastLogFile, lFile);
485 stringNowReplace(lastLogFile, globalTapeConfig.device);
486 strcat(lastLogFile, ".lp");
487 strcpy(ErrorlogFile, eFile);
488 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
490 /* Now open the device file */
491 devFile = fopen(paramFile, "r");
493 ERROR_EXIT(0); /* CFG file doesn't exist for non-XBSA and that's ok */
496 /* Read each line of the Configuration file */
497 while (fgets(line, LINESIZE - 1, devFile)) {
498 cnt = sscanf(line, "%s %s", cmd, value);
501 printf("Bad line in %s: %s\n", paramFile, line);
505 for (cnt = 0; cnt < strlen(cmd); cnt++)
506 if (islower(cmd[cnt]))
507 cmd[cnt] = toupper(cmd[cnt]);
509 if (!strcmp(cmd, "NAME_CHECK")) {
512 ("Warning: The %s parameter is ignored with a Backup Service\n",
517 for (cnt = 0; cnt < strlen(value); cnt++)
518 if (islower(value[cnt]))
519 value[cnt] = toupper(value[cnt]);
521 if (!strcmp(value, "NO")) {
522 printf("Dump tape name check is disabled\n");
525 printf("Dump tape name check is enabled\n");
530 else if (!strcmp(cmd, "MOUNT")) {
533 ("Warning: The %s parameter is ignored with a Backup Service\n",
538 opencallout = (char *)malloc(strlen(value) + 1);
539 strcpy(opencallout, value);
540 printf("Tape mount callout routine is %s\n", opencallout);
543 else if (!strcmp(cmd, "UNMOUNT")) {
546 ("Warning: The %s parameter is ignored with a Backup Service\n",
551 closecallout = (char *)malloc(strlen(value) + 1);
552 strcpy(closecallout, value);
553 printf("Tape unmount callout routine is %s\n", closecallout);
556 else if (!strcmp(cmd, "ASK")) {
557 for (cnt = 0; cnt < strlen(value); cnt++)
558 if (islower(value[cnt]))
559 value[cnt] = toupper(value[cnt]);
561 if (!strcmp(value, "NO")) {
562 printf("Operator queries are disabled\n");
565 printf("Operator queries are enabled\n");
570 else if (!strcmp(cmd, "FILE")) {
573 ("Warning: The %s parameter is ignored with a Backup Service\n",
578 for (cnt = 0; cnt < strlen(value); cnt++)
579 if (islower(value[cnt]))
580 value[cnt] = toupper(value[cnt]);
582 if (!strcmp(value, "YES")) {
583 printf("Will dump to a file\n");
586 printf("Will not dump to a file\n");
591 else if (!strcmp(cmd, "AUTOQUERY")) {
594 ("Warning: The %s parameter is ignored with a Backup Service\n",
599 for (cnt = 0; cnt < strlen(value); cnt++)
600 if (islower(value[cnt]))
601 value[cnt] = toupper(value[cnt]);
603 if (!strcmp(value, "NO")) {
604 printf("Auto query is disabled\n");
607 printf("Auto query is enabled\n");
612 else if (!strcmp(cmd, "BUFFERSIZE")) {
614 afs_int32 tapeblocks;
617 if (atocl(value, 'K', &size)) {
618 fprintf(stderr, "BUFFERSIZE parse error\n");
622 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
623 * determine BufferSize needed for that many tapeblocks.
625 tapeblocks = size / 16;
628 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16));
629 BufferSize = tapeblocks * BUTM_BLOCKSIZE;
632 if (atocl(value, 'B', &size)) {
633 fprintf(stderr, "BUFFERSIZE parse error\n");
636 if (size < XBSAMINBUFFER)
637 size = XBSAMINBUFFER;
638 if (size > XBSAMAXBUFFER)
639 size = XBSAMAXBUFFER;
640 printf("XBSA buffer size is %u Bytes\n", size);
647 /* All the xbsa spacific parameters */
648 else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE")
649 || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD")
650 || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) {
651 printf("This binary does not have XBSA support\n");
655 else if (!strcmp(cmd, "TYPE")) { /* required for XBSA */
658 ("Warning: The %s parameter is ignored with a tape drive\n",
663 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
664 if (islower(value[cnt]))
665 value[cnt] = toupper(value[cnt]);
667 if (strcmp(value, "TSM") == 0) {
668 xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */
670 printf("Configuration file error, %s %s is not recognized\n",
672 xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
674 printf("XBSA type is %s\n",
676 XBSA_SERVER_TYPE_UNKNOWN) ? "Unknown" : value));
679 else if (!strcmp(cmd, "NODE")) {
682 ("Warning: The %s parameter is ignored with a tape drive\n",
686 xbsaObjectOwner = malloc(strlen(value) + 1);
687 strcpy(xbsaObjectOwner, value);
688 printf("XBSA node is %s\n", xbsaObjectOwner);
691 else if (!strcmp(cmd, "SERVER")) { /* required for XBSA */
694 ("Warning: The %s parameter is ignored with a tape drive\n",
698 adsmServerName = malloc(strlen(value) + 1);
699 strcpy(adsmServerName, value);
700 printf("XBSA server is %s\n", adsmServerName);
703 else if (!strcmp(cmd, "PASSWORD")) { /* This or PASSFILE required for XBSA */
706 ("Warning: The %s parameter is ignored with a tape drive\n",
712 ("Warning: The %s parameter is ignored. Already read password\n",
717 xbsaSecToken = malloc(strlen(value) + 1);
718 strcpy(xbsaSecToken, value);
719 printf("XBSA Password has been read\n");
722 else if (!strcmp(cmd, "PASSFILE")) { /* This or PASSWORD required for XBSA */
726 ("Warning: The %s parameter is ignored with a tape drive\n",
732 ("Warning: The %s parameter is ignored. Already read password\n",
737 pwdFile = fopen(value, "r");
740 ("Configuration file error, cannot open password file %s\n",
744 xbsaSecToken = malloc(LINESIZE);
745 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
747 ("Configuration file error, cannot read password file %s\n",
751 printf("XBSA password retrieved from password file\n");
754 else if (!strcmp(cmd, "MGMTCLASS")) { /* XBSA */
757 ("Warning: The %s parameter is ignored with a tape drive\n",
761 xbsalGName = malloc(strlen(value) + 1);
762 strcpy(xbsalGName, value);
763 printf("XBSA management class is %s\n", xbsalGName);
767 else if (!strcmp(cmd, "MAXPASS")) {
768 maxpass = SafeATOL(value);
769 if (maxpass < PASSESMIN)
771 if (maxpass > PASSESMAX)
773 printf("MAXPASS is %d\n", maxpass);
776 else if (!strcmp(cmd, "GROUPID")) {
777 groupId = SafeATOL(value);
778 if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
779 printf("Configuration file error, %s %s is invalid\n", cmd,
783 printf("Group Id is %d\n", groupId);
786 else if (!strcmp(cmd, "LASTLOG")) {
787 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
788 if (islower(value[cnt]))
789 value[cnt] = toupper(value[cnt]);
791 lastLog = (strcmp(value, "YES") == 0);
792 printf("Will %sgenerate a last log\n", (lastLog ? "" : "not "));
795 else if (!strcmp(cmd, "CENTRALLOG")) {
796 centralLogFile = malloc(strlen(value) + 1);
797 strcpy(centralLogFile, value);
798 printf("Central log file is %s\n", centralLogFile);
801 else if (!strcmp(cmd, "STATUS")) {
802 if (atocl(value, 'B', &statusSize)) {
803 fprintf(stderr, "STATUS parse error\n");
806 if (statusSize < MINSTATUS)
807 statusSize = MINSTATUS;
808 if (statusSize > MAXSTATUS)
809 statusSize = MAXSTATUS;
813 printf("Warning: Unrecognized configuration parameter: %s", line);
818 /* Statussize is in bytes and requires that BufferSize be set first */
819 statusSize *= BufferSize;
821 statusSize = 0x7fffffff; /*max size */
822 printf("Status every %ld Bytes\n", statusSize);
829 /* If the butc is configured as XBSA, check for required parameters */
831 if (!code && CONF_XBSA) {
832 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
834 ("Configuration file error, the TYPE parameter must be specified, or\n");
835 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
839 if (!adsmServerName) {
841 ("Configuration file error, the SERVER parameter must be specified\n");
846 ("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
856 struct cmd_syndesc *as;
860 register afs_int32 code;
861 struct rx_securityClass *(securityObjects[3]);
862 struct rx_service *service;
863 struct ktc_token ttoken;
866 /*process arguments */
867 afs_int32 portOffset = 0;
869 #ifdef AFS_PTHREAD_ENV
870 pthread_t dbWatcherPid;
871 pthread_attr_t tattr;
874 PROCESS dbWatcherPid;
879 /*initialize the error tables */
880 initialize_KA_error_table();
881 initialize_RXK_error_table();
882 initialize_KTC_error_table();
883 initialize_ACFG_error_table();
884 initialize_CMD_error_table();
885 initialize_VL_error_table();
886 initialize_BUTM_error_table();
887 initialize_BUTC_error_table();
889 initialize_BUTX_error_table();
891 initialize_VOLS_error_table();
892 initialize_BUDB_error_table();
893 initialize_BUCD_error_table();
895 if (as->parms[0].items) {
896 portOffset = SafeATOL(as->parms[0].items->data);
897 if (portOffset == -1) {
898 fprintf(stderr, "Illegal port offset '%s'\n",
899 as->parms[0].items->data);
901 } else if (portOffset > BC_MAXPORTOFFSET) {
902 fprintf(stderr, "%u exceeds max port offset %u\n", portOffset,
908 xbsaType = XBSA_SERVER_TYPE_NONE; /* default */
909 if (as->parms[3].items) { /* -device */
910 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
911 globalTapeConfig.fileMarkSize = 0;
912 globalTapeConfig.portOffset = portOffset;
913 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
914 xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */
916 /* Search for an entry in tapeconfig file */
917 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
919 fprintf(stderr, "Problem in reading config file %s\n",
923 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
924 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
927 ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE);
930 if (as->parms[6].items) { /* -restoretofile */
931 int s = strlen(as->parms[6].items->data);
932 restoretofile = malloc(s + 1);
933 strncpy(restoretofile, as->parms[6].items->data, s + 1);
934 printf("Restore to file '%s'\n", restoretofile);
937 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
938 * the exact xbsaType within the call (won't be unknown) - double check.
940 code = GetConfigParams(pFile, portOffset);
944 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
946 ("\nConfiguration file error, the TYPE parameter must be specified, or\n");
947 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
952 /* Not compiled for XBSA code so we can't support it */
954 printf("\nNo entry found in %s for port %d\n", tapeConfigFile,
956 printf("This binary does not have XBSA support\n");
961 /* Open the log files. The pathnames were set in GetConfigParams() */
962 logIO = fopen(logFile, "a");
964 fprintf(stderr, "Failed to open %s\n", logFile);
967 ErrorlogIO = fopen(ErrorlogFile, "a");
969 fprintf(stderr, "Failed to open %s\n", ErrorlogFile);
973 lastLogIO = fopen(lastLogFile, "a");
975 fprintf(stderr, "Failed to open %s\n", lastLogFile);
979 if (centralLogFile) {
982 char path[AFSDIR_PATH_MAX];
984 statcode = stat(centralLogFile, &sbuf);
985 centralLogIO = fopen(centralLogFile, "a");
987 fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile,
992 /* Make sure it is not in AFS, has to have been created first */
993 if (!realpath(centralLogFile, path)) {
995 "Warning: can't determine real path of '%s' (%d)\n",
996 centralLogFile, errno);
998 if (strncmp(path, "/afs/", 5) == 0) {
999 fprintf(stderr, "The central log '%s' should not be in AFS\n",
1006 /* Write header if created it */
1009 "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
1011 "----- ------------------- ------------------- -------- ---------\n";
1012 /* File didn't exist before so write the header lines */
1013 fwrite(h1, strlen(h1), 1, centralLogIO);
1014 fwrite(h2, strlen(h2), 1, centralLogIO);
1015 fflush(centralLogIO);
1019 if (as->parms[1].items) {
1020 debugLevel = SafeATOL(as->parms[1].items->data);
1021 if (debugLevel == -1) {
1022 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
1027 /* Setup XBSA library interface */
1030 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
1031 if (rc != XBSA_SUCCESS) {
1032 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
1036 forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */
1038 printf("Force XBSA multiple server support\n");
1040 rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName);
1041 if (rc != XBSA_SUCCESS)
1047 if (as->parms[2].items)
1048 strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
1052 if (as->parms[4].items)
1055 localauth = (as->parms[5].items ? 1 : 0);
1057 code = rx_Init(htons(BC_TAPEPORT + portOffset));
1059 TapeLog(0, 0, code, 0, "rx init failed on port %u\n",
1060 BC_TAPEPORT + portOffset);
1063 rx_SetRxDeadTime(150);
1065 /* Establish connection with the vldb server */
1066 code = vldbClientInit(0, localauth, cellName, &cstruct, &ttoken);
1068 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1072 strcpy(globalCellName, cellName);
1074 /*initialize the dumpNode list */
1075 InitNodeList(portOffset);
1078 (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode)));
1079 Lock_Init(&(deviceLatch->lock));
1080 deviceLatch->flags = 0;
1082 /* initialize database support, volume support, and logs */
1084 /* Create a single security object, in this case the null security
1085 * object, for unauthenticated connections, which will be used to control
1086 * security on connections made to this server
1089 securityObjects[0] = rxnull_NewServerSecurityObject();
1090 securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */
1091 if (!securityObjects[0]) {
1092 TLog(0, "rxnull_NewServerSecurityObject");
1097 rx_NewService(0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest);
1099 TLog(0, "rx_NewService");
1102 rx_SetMaxProcs(service, 4);
1104 /* Establish connection to the backup database */
1105 code = udbClientInit(0, localauth, cellName);
1107 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1110 /* This call is here to verify that we are authentiated.
1111 * The call does nothing and will return BUDB_NOTPERMITTED
1112 * if we don't belong.
1114 code = bcdb_deleteDump(0, 0, 0, 0);
1115 if (code == BUDB_NOTPERMITTED) {
1116 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1121 #ifdef AFS_PTHREAD_ENV
1122 code = pthread_attr_init(&tattr);
1124 TapeLog(0, 0, code, 0,
1125 "Can't pthread_attr_init database monitor task");
1128 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1130 TapeLog(0, 0, code, 0,
1131 "Can't pthread_attr_setdetachstate database monitor task");
1135 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1136 AFS_SIGSET_RESTORE();
1139 LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2,
1140 "dbWatcher", &dbWatcherPid);
1143 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1147 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1148 portOffset, debugLevel);
1149 TLog(0, "Token expires: %s\n", cTIME(&ttoken.endTime));
1151 rx_StartServer(1); /* Donate this process to the server process pool */
1152 TLog(0, "Error: StartServer returned");
1156 #ifndef AFS_NT40_ENV
1157 #include "AFS_component_version_number.c"
1164 register struct cmd_syndesc *ts;
1165 register struct cmd_item *ti;
1167 #ifdef AFS_AIX32_ENV
1169 * The following signal action for AIX is necessary so that in case of a
1170 * crash (i.e. core is generated) we can include the user's data section
1171 * in the core dump. Unfortunately, by default, only a partial core is
1172 * generated which, in many cases, isn't too useful.
1174 struct sigaction nsa;
1176 sigemptyset(&nsa.sa_mask);
1177 nsa.sa_handler = SIG_DFL;
1178 nsa.sa_flags = SA_FULLDUMP;
1179 sigaction(SIGSEGV, &nsa, NULL);
1180 sigaction(SIGABRT, &nsa, NULL);
1185 ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, "tape coordinator");
1186 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset");
1187 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2");
1188 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1189 cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1190 "tape device path");
1191 cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL,
1192 "do not query operator for first tape");
1193 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL,
1194 "create tickets from KeyFile");
1195 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE),
1196 "file to restore to");
1197 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL | CMD_HIDE),
1198 "Force multiple XBSA server support");
1200 /* Initialize dirpaths */
1201 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1203 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1205 fprintf(stderr, "Unable to obtain AFS server directory.\n");
1209 /* setup the file paths */
1210 strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1212 strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1214 strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/",
1216 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH);
1218 /* special case "no args" case since cmd_dispatch gives help message
1222 ts = (struct cmd_syndesc *)malloc(sizeof(struct cmd_syndesc));
1223 memset(ts, 0, sizeof(*ts));
1225 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1228 ts->parms[0].items = ti;
1229 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1232 ts->parms[1].items = ti;
1233 ts->parms[2].items = (struct cmd_item *)NULL;
1234 ts->parms[3].items = (struct cmd_item *)NULL;
1235 ts->parms[4].items = (struct cmd_item *)NULL;
1236 ts->parms[5].items = (struct cmd_item *)NULL;
1237 return WorkerBee(ts, NULL);
1239 return cmd_Dispatch(argc, argv);