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 <afs/param.h>
11 #include <sys/types.h>
15 #include <WINNT/afsevent.h>
17 #include <netinet/in.h>
20 #include <afs/procmgmt.h>
22 #include <afs/afsint.h>
24 #ifdef AFS_PTHREAD_ENV
27 #include <afs/assert.h>
29 #include <afs/prs_fs.h>
32 #include <afs/vlserver.h>
35 #include <afs/afsutil.h>
37 #include <rx/rx_globals.h>
40 #include <afs/cellconfig.h>
42 #include <afs/volser.h>
44 #include <afs/com_err.h>
47 #include <afs/tcdata.h>
48 #include <afs/bubasics.h>
50 #include "error_macros.h"
51 #include <afs/budb_errs.h>
53 #include "butc_xbsa.h"
55 #define N_SECURITY_OBJECTS 3
56 #define ERRCODE_RANGE 8 /* from error_table.h */
58 #define TE_PREFIX "TE"
59 #define TL_PREFIX "TL"
60 #define CFG_PREFIX "CFG"
62 struct ubik_client *cstruct;
63 extern void TC_ExecuteRequest();
64 extern int dbWatcher();
65 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
66 extern struct rx_service *rx_NewService();
67 FILE *logIO, *ErrorlogIO, *centralLogIO, *lastLogIO;
68 char lFile[AFSDIR_PATH_MAX];
70 char ErrorlogFile[256];
71 char lastLogFile[256];
72 char eFile[AFSDIR_PATH_MAX];
73 char tapeConfigFile[AFSDIR_PATH_MAX];
74 char pFile[AFSDIR_PATH_MAX];
76 struct tapeConfig globalTapeConfig;
77 struct deviceSyncNode *deviceLatch;
78 char globalCellName[64];
79 char *whoami = "butc";
81 /* GLOBAL CONFIGURATION PARAMETERS */
92 /* XBSA Global Parameters */
95 struct butx_transactionInfo butxInfo;
97 #define rpc_c_protect_level_default 0
98 afs_uint32 dumpRestAuthnLevel = rpc_c_protect_level_default;
99 char *xbsaObjectOwner;
100 char *appObjectOwner;
101 char *adsmServerName;
111 #define MINGROUPID 0x1
112 #define MAXGROUPID 0x7FFFFFFF
113 afs_int32 statusSize;
115 #define MAXSTATUS 0x7fffffff
116 afs_int32 BufferSize; /* Size in B stored for data */
117 char *centralLogFile;
118 afs_int32 lastLog; /* Log last pass info */
120 /* dummy routine for the audit work. It should do nothing since audits */
121 /* occur at the server level and bos is not a server. */
122 osi_audit() {return 0;}
124 static afs_int32 SafeATOL(anum)
125 register char *anum; {
126 register afs_int32 total;
131 if (tc < '0' || tc > '9') return -1;
140 * Convert a string into an afs_int32.
141 * Returned afs_int32 is in Bytes, Kb, Mb, Gb, or Tb. Based on crunit char.
142 * This routine only converts unsigned float values.
143 * The returned value is a whole number.
145 * numstring - text string to be converted.
146 * crunit - value returned in 'B', 'K', 'M', 'G', 'T'.
147 * ' ' or NULL ==> 'B' (bytes).
149 * number - returned value in requested crunit - rounded
150 * to nearest whole number.
153 * -1 - error in conversion
155 * should deal with signed numbers. Should signal error if no digits
158 atocl(numstring, crunit, number)
160 char crunit; /* Units to report number in */
170 /* Determine which units to report in */
203 count = sscanf(numstring, "%f%c%s", (unsigned char *)&total, &cunit, rest);
204 if ((count > 2) || (count <= 0))
207 cunit = 'B'; /* bytes */
241 /* Go to correct unit */
242 for (; units < runits; units += 3)
244 for (; units > runits; units -= 3)
247 total += 0.5; /* Round up */
248 if ((total > 0x7fffffff) || (total < 0)) /* Don't go over 2G */
255 /* replace last two ocurrences of / by _ */
256 static stringReplace(name)
263 pos = strrchr(name,'/');
266 pos = strrchr(name,'/');
272 static stringNowReplace (logFile, deviceName)
273 char *logFile, *deviceName;
277 char storeDevice[256];
278 int mvFlag = 0, devPrefLen;
280 char devPrefix[] = "\\\\.";
282 char devPrefix[] = "/dev";
285 devPrefLen = strlen(devPrefix);
286 strcpy(storeDevice, deviceName);
287 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
288 deviceName += devPrefLen;
291 while (pos = strchr(deviceName, devPrefix[0])) /* look for / or \ */
293 strcat (logFile, deviceName);
294 /* now put back deviceName to the way it was */
297 deviceName -= devPrefLen;
299 strcpy (deviceName, storeDevice);
306 * get the configuration information for a particular tape device
307 * as specified by the portoffset
309 * filename - full pathname of file containing the tape device
310 * configuration information
311 * config - for return results
312 * portOffset - for which configuration is required
314 * logging not available when this routine is called
315 * caller return value checks
317 * 0 => Found entry with same port, return info in config.
318 * -1 => Error encountered trying to read the file.
319 * 1 => Desired entry does not exist or file does not exist.
323 static afs_int32 GetDeviceConfig(filename, config, portOffset)
325 struct tapeConfig *config;
326 afs_int32 portOffset;
330 char devName[LINESIZE], tcapacity[LINESIZE],
331 tfmsize[LINESIZE], trest[LINESIZE];
335 afs_int32 code=0, count;
337 /* Initialize the config struct */
338 config->capacity = 0;
339 config->fileMarkSize = 0;
340 config->portOffset = portOffset;
341 strcpy(config->device, "");
343 devFile = fopen(filename,"r");
345 if (errno == ENOENT) ERROR_EXIT(1);
346 fprintf(stderr, "Error %d: Can't open %s\n", errno, filename);
350 while ( fgets(line,LINESIZE-1,devFile) ) {
351 count = sscanf(line, "%s %s %s %u%s\n",
352 tcapacity, tfmsize, devName, &aport, trest);
355 if ( atocl(tcapacity, 'K', &capacity) ) {
356 fprintf(stderr, "tapeconfig: Tape capacity parse error in: %s\n", line);
359 if ( atocl(tfmsize, 'B', &fmSize) ) {
360 fprintf(stderr, "tapeconfig: File-mark size parse error in: %s\n", line);
364 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
366 capacity = 0x7fffffff;
369 fprintf(stderr, "tapeconfig: Parse error in: %s\n", line);
374 if ((aport < 0) || (aport > BC_MAXPORTOFFSET)) {
375 fprintf(stderr, "tapeconfig: Port offset parse error in: %s\n", line);
379 if (aport != portOffset)
383 fprintf(stderr, "Invalid file mark size, %d, in: %s\n", fmSize, line);
387 config->capacity = capacity;
388 config->fileMarkSize = fmSize;
389 config->portOffset = aport;
390 strncpy(config->device, devName, 100);
395 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
399 if (devFile) fclose(devFile);
405 static afs_int32 GetConfigParams(filename, port)
411 char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
415 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
416 dump_namecheck = 1; /* check tape name on dumps */
417 queryoperator = 1; /* can question operator */
418 autoQuery = 1; /* prompt for first tape */
419 isafile = 0; /* Do not dump to a file */
420 opencallout = (char *)0; /* open callout routine */
421 closecallout = (char *)0; /* close callout routine */
422 tapemounted = 0; /* tape is not mounted */
424 BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
425 dumpRestAuthnLevel = rpc_c_protect_level_default;
426 xbsaObjectOwner = (char *)0; /* bsaObjectOwner */
427 appObjectOwner = (char *)0; /* appObjectOwner */
428 adsmServerName = (char *)0; /* TSM server name - same as ADSM */
429 xbsaSecToken = (char *)0; /* XBSA sercurity token */
430 xbsalGName = (char *)0; /* XBSA IGName */
432 BufferSize = BUTM_BLOCKSIZE;
434 centralLogFile = (char *)0; /* Log for all butcs */
435 centralLogIO = 0; /* Log for all butcs */
436 statusSize = 0; /* size before status message */
437 maxpass = PASSESDFLT; /* dump passes */
438 lastLog = 0; /* separate log for last pass */
439 lastLogIO = 0; /* separate log for last pass */
440 groupId = 0; /* Group id for multiple dumps */
442 /* Try opening the CFG_<port> file */
443 sprintf(paramFile, "%s_%d", filename, port);
444 devFile = fopen(paramFile, "r");
446 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
447 sprintf(logFile, "%s_%d", lFile, port);
448 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
449 sprintf(ErrorlogFile, "%s_%d", eFile, port);
450 } else if (CONF_XBSA) {
451 /* If configured as XBSA, a configuration file CFG_<port> must exist */
452 printf("Cannot open configuration file %s", paramFile);
455 /* Try the CFG_<device> name as the device file */
456 strcpy(paramFile, filename);
457 stringNowReplace(paramFile, globalTapeConfig.device);
458 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
459 strcpy(logFile,lFile);
460 stringNowReplace(logFile,globalTapeConfig.device);
461 strcpy(lastLogFile,lFile);
462 stringNowReplace(lastLogFile,globalTapeConfig.device);
463 strcat(lastLogFile, ".lp");
464 strcpy(ErrorlogFile,eFile);
465 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
467 /* Now open the device file */
468 devFile = fopen(paramFile, "r");
470 ERROR_EXIT(0);/* CFG file doesn't exist for non-XBSA and that's ok */
473 /* Read each line of the Configuration file */
474 while (fgets(line,LINESIZE-1,devFile)) {
475 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])) cmd[cnt] = toupper(cmd[cnt]);
486 if (!strcmp(cmd,"NAME_CHECK"))
489 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
493 for (cnt=0; cnt<strlen(value); cnt++)
494 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
496 if (!strcmp(value,"NO"))
498 printf("Dump tape name check is disabled\n");
503 printf("Dump tape name check is enabled\n");
508 else if (!strcmp(cmd,"MOUNT"))
511 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
515 opencallout = (char*)malloc(strlen(value)+1);
516 strcpy(opencallout, value);
517 printf("Tape mount callout routine is %s\n", opencallout);
520 else if (!strcmp(cmd,"UNMOUNT"))
523 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
527 closecallout = (char*)malloc(strlen(value)+1);
528 strcpy(closecallout, value);
529 printf("Tape unmount callout routine is %s\n", closecallout);
532 else if (!strcmp(cmd,"ASK"))
534 for (cnt=0; cnt<strlen(value); cnt++)
535 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
537 if (!strcmp(value,"NO"))
539 printf("Operator queries are disabled\n");
544 printf("Operator queries are enabled\n");
549 else if (!strcmp(cmd,"FILE"))
552 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
556 for (cnt=0; cnt<strlen(value); cnt++)
557 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
559 if (!strcmp(value,"YES"))
561 printf("Will dump to a file\n");
566 printf("Will not dump to a file\n");
571 else if (!strcmp(cmd,"AUTOQUERY"))
574 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
578 for (cnt=0; cnt<strlen(value); cnt++)
579 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
581 if (!strcmp(value,"NO"))
583 printf("Auto query is disabled\n");
588 printf("Auto query is enabled\n");
593 else if (!strcmp(cmd,"BUFFERSIZE"))
596 afs_int32 tapeblocks;
599 if ( atocl(value, 'K', &size) ) {
600 fprintf(stderr, "BUFFERSIZE parse error\n");
604 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
605 * determine BufferSize needed for that many tapeblocks.
607 tapeblocks = size / 16;
608 if (tapeblocks <= 0) tapeblocks = 1;
609 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks*16));
610 BufferSize = tapeblocks * BUTM_BLOCKSIZE;
613 if ( atocl(value, 'B', &size) ) {
614 fprintf(stderr, "BUFFERSIZE parse error\n");
617 if (size < XBSAMINBUFFER) size = XBSAMINBUFFER;
618 if (size > XBSAMAXBUFFER) size = XBSAMAXBUFFER;
619 printf("XBSA buffer size is %u Bytes\n", size);
629 /* All the xbsa spacific parameters */
630 else if (!strcmp(cmd,"TYPE") || !strcmp(cmd,"NODE") ||
631 !strcmp(cmd,"SERVER") || !strcmp(cmd,"PASSWORD") ||
632 !strcmp(cmd,"PASSFILE") || !strcmp(cmd,"MGMTCLASS"))
634 printf("This binary does not have XBSA support\n");
638 else if (!strcmp(cmd,"TYPE")) /* required for XBSA */
641 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
645 for (cnt=0; (size_t)cnt<strlen(value); cnt++)
646 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
648 if (strcmp(value,"TSM") == 0) {
649 xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */
651 printf("Configuration file error, %s %s is not recognized\n", cmd, value);
652 xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
654 printf("XBSA type is %s\n",
655 ((xbsaType == XBSA_SERVER_TYPE_UNKNOWN)?"Unknown":value));
658 else if (!strcmp(cmd,"NODE"))
661 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
664 xbsaObjectOwner = malloc(strlen(value)+1);
665 strcpy(xbsaObjectOwner, value);
666 printf("XBSA node is %s\n", xbsaObjectOwner);
669 else if (!strcmp(cmd,"SERVER")) /* required for XBSA */
672 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
675 adsmServerName = malloc(strlen(value)+1);
676 strcpy(adsmServerName, value);
677 printf("XBSA server is %s\n", adsmServerName);
680 else if (!strcmp(cmd,"PASSWORD")) /* This or PASSFILE required for XBSA */
683 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
687 printf("Warning: The %s parameter is ignored. Already read password\n", cmd);
691 xbsaSecToken = malloc(strlen(value)+1);
692 strcpy(xbsaSecToken, value);
693 printf("XBSA Password has been read\n");
696 else if (!strcmp(cmd,"PASSFILE")) /* This or PASSWORD required for XBSA */
700 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
704 printf("Warning: The %s parameter is ignored. Already read password\n", cmd);
708 pwdFile = fopen(value,"r");
710 printf("Configuration file error, cannot open password file %s\n", value);
713 xbsaSecToken = malloc(LINESIZE);
714 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
715 printf("Configuration file error, cannot read password file %s\n", value);
718 printf("XBSA password retrieved from password file\n");
721 else if (!strcmp(cmd,"MGMTCLASS")) /* XBSA */
724 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
727 xbsalGName = malloc(strlen(value)+1);
728 strcpy(xbsalGName, value);
729 printf("XBSA management class is %s\n", xbsalGName);
733 else if (!strcmp(cmd,"MAXPASS"))
735 maxpass = SafeATOL(value);
736 if (maxpass < PASSESMIN) maxpass = PASSESMIN;
737 if (maxpass > PASSESMAX) maxpass = PASSESMAX;
738 printf("MAXPASS is %d\n", maxpass);
741 else if (!strcmp(cmd,"GROUPID"))
743 groupId = SafeATOL(value);
744 if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
745 printf("Configuration file error, %s %s is invalid\n", cmd, value);
748 printf("Group Id is %d\n", groupId);
751 else if (!strcmp(cmd,"LASTLOG"))
753 for (cnt=0; (size_t)cnt<strlen(value); cnt++)
754 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
756 lastLog = (strcmp(value,"YES") == 0);
757 printf("Will %sgenerate a last log\n", (lastLog?"":"not "));
760 else if (!strcmp(cmd,"CENTRALLOG"))
762 centralLogFile = malloc(strlen(value)+1);
763 strcpy(centralLogFile, value);
764 printf("Central log file is %s\n", centralLogFile);
767 else if (!strcmp(cmd,"STATUS"))
769 if (atocl(value, 'B', &statusSize)) {
770 fprintf(stderr, "STATUS parse error\n");
773 if (statusSize < MINSTATUS) statusSize = MINSTATUS;
774 if (statusSize > MAXSTATUS) statusSize = MAXSTATUS;
778 printf("Warning: Unrecognized configuration parameter: %s", line);
783 /* Statussize is in bytes and requires that BufferSize be set first */
784 statusSize *= BufferSize;
785 if (statusSize < 0) statusSize = 0x7fffffff; /*max size*/
786 printf("Status every %ld Bytes\n", statusSize);
790 if (devFile) fclose(devFile);
792 /* If the butc is configured as XBSA, check for required parameters */
794 if (!code && CONF_XBSA) {
795 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
796 printf("Configuration file error, the TYPE parameter must be specified, or\n");
797 printf("an entry must exist in %s for port %d\n", tapeConfigFile, port);
800 if (!adsmServerName) {
801 printf("Configuration file error, the SERVER parameter must be specified\n");
805 printf("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
813 static WorkerBee(as, arock)
814 struct cmd_syndesc *as;
817 register afs_int32 code;
818 struct rx_securityClass *(securityObjects[3]);
819 struct rx_service *service;
820 struct ktc_token ttoken;
823 /*process arguments */
824 afs_int32 portOffset = 0;
826 #ifdef AFS_PTHREAD_ENV
827 pthread_t dbWatcherPid;
828 pthread_attr_t tattr;
831 PROCESS dbWatcherPid;
836 /*initialize the error tables */
837 initialize_ka_error_table();
838 initialize_rxk_error_table();
839 initialize_ktc_error_table();
840 initialize_acfg_error_table();
841 initialize_cmd_error_table();
842 initialize_vl_error_table();
843 initialize_butm_error_table();
844 initialize_butc_error_table();
846 initialize_butx_error_table();
848 initialize_vols_error_table();
849 initialize_budb_error_table();
850 initialize_bucd_error_table();
852 if (as->parms[0].items)
854 portOffset = SafeATOL(as->parms[0].items->data);
855 if (portOffset == -1)
857 fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data);
860 else if (portOffset > BC_MAXPORTOFFSET)
862 fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET);
867 xbsaType = XBSA_SERVER_TYPE_NONE; /* default */
868 if (as->parms[3].items) { /* -device */
869 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
870 globalTapeConfig.fileMarkSize = 0;
871 globalTapeConfig.portOffset = portOffset;
872 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
873 xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */
875 /* Search for an entry in tapeconfig file */
876 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
878 fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile);
881 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
882 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
884 xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE);
887 if (as->parms[6].items) { /* -restoretofile */
888 int s = strlen(as->parms[6].items->data);
889 restoretofile = malloc(s+1);
890 strncpy(restoretofile, as->parms[6].items->data, s+1);
891 printf("Restore to file '%s'\n", restoretofile);
894 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
895 * the exact xbsaType within the call (won't be unknown) - double check.
897 code = GetConfigParams(pFile, portOffset);
898 if (code) exit(code);
900 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
901 printf("\nConfiguration file error, the TYPE parameter must be specified, or\n");
902 printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset);
906 /* Not compiled for XBSA code so we can't support it */
908 printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset);
909 printf("This binary does not have XBSA support\n");
914 /* Open the log files. The pathnames were set in GetConfigParams() */
915 logIO = fopen(logFile,"a");
917 fprintf(stderr,"Failed to open %s\n",logFile);
920 ErrorlogIO = fopen(ErrorlogFile,"a");
922 fprintf(stderr,"Failed to open %s\n",ErrorlogFile);
926 lastLogIO = fopen(lastLogFile,"a");
928 fprintf(stderr,"Failed to open %s\n", lastLogFile);
932 if (centralLogFile) {
935 char path[AFSDIR_PATH_MAX];
937 statcode = stat(centralLogFile, &sbuf);
938 centralLogIO = fopen(centralLogFile,"a");
940 fprintf(stderr,"Failed to open %s; error %d\n",centralLogFile, errno);
945 /* Make sure it is not in AFS, has to have been created first */
946 if (!realpath(centralLogFile, path)) {
947 fprintf(stderr,"Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno);
949 if (strncmp(path,"/afs/",5) == 0) {
950 fprintf(stderr,"The central log '%s' should not be in AFS\n", centralLogFile);
956 /* Write header if created it */
958 char *h1="TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
959 char *h2="----- ------------------- ------------------- -------- ---------\n";
960 /* File didn't exist before so write the header lines */
961 fwrite(h1, strlen(h1), 1, centralLogIO);
962 fwrite(h2, strlen(h2), 1, centralLogIO);
963 fflush(centralLogIO);
967 if (as->parms[1].items)
969 debugLevel = SafeATOL(as->parms[1].items->data);
972 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
978 /* Setup XBSA library interface */
981 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
982 if (rc != XBSA_SUCCESS) {
983 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
987 forcemultiple = (as->parms[7].items ? 1 : 0); /*-xbsaforcemultiple */
989 printf("Force XBSA multiple server support\n");
991 rc = InitToServer(0/*taskid*/, &butxInfo, adsmServerName);
992 if (rc != XBSA_SUCCESS) return(1);
997 if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
998 else cellName[0] = '\0';
1000 if (as->parms[4].items) autoQuery = 0;
1002 localauth = (as->parms[5].items ? 1 : 0);
1004 code = rx_Init(htons(BC_TAPEPORT + portOffset));
1007 TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset);
1010 rx_SetRxDeadTime(150);
1012 /* Establish connection with the vldb server */
1013 code = vldbClientInit(0, localauth, cellName, &cstruct, &ttoken);
1016 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1020 strcpy(globalCellName, cellName);
1022 /*initialize the dumpNode list */
1023 InitNodeList(portOffset);
1025 deviceLatch = (struct deviceSyncNode *)(malloc (sizeof(struct deviceSyncNode)));
1026 Lock_Init(&(deviceLatch->lock));
1027 deviceLatch->flags = 0;
1029 /* initialize database support, volume support, and logs */
1031 /* Create a single security object, in this case the null security
1032 * object, for unauthenticated connections, which will be used to control
1033 * security on connections made to this server
1036 securityObjects[0] = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
1037 securityObjects[1] = (struct rx_securityClass *) 0; /* don't bother with rxvab */
1038 if ( !securityObjects[0] )
1040 TLog(0, "rxnull_NewServerSecurityObject");
1044 service = rx_NewService(0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest);
1047 TLog(0, "rx_NewService");
1050 rx_SetMaxProcs(service, 4);
1052 /* Establish connection to the backup database */
1053 code = udbClientInit(0, localauth, cellName);
1056 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1059 /* This call is here to verify that we are authentiated.
1060 * The call does nothing and will return BUDB_NOTPERMITTED
1061 * if we don't belong.
1063 code = bcdb_deleteDump(0,0,0,0);
1064 if (code == BUDB_NOTPERMITTED) {
1065 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1070 #ifdef AFS_PTHREAD_ENV
1071 code = pthread_attr_init(&tattr);
1074 TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task");
1077 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1080 TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task");
1084 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1085 AFS_SIGSET_RESTORE();
1087 code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, 2, "dbWatcher", &dbWatcherPid);
1091 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1095 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1096 portOffset, debugLevel);
1097 TLog(0, "Token expires: %s\n", cTIME(&ttoken.endTime));
1099 rx_StartServer(1); /* Donate this process to the server process pool */
1100 TLog(0, "Error: StartServer returned");
1104 #ifndef AFS_NT40_ENV
1105 #include "AFS_component_version_number.c"
1112 register struct cmd_syndesc *ts;
1113 register struct cmd_item *ti;
1115 #ifdef AFS_AIX32_ENV
1117 * The following signal action for AIX is necessary so that in case of a
1118 * crash (i.e. core is generated) we can include the user's data section
1119 * in the core dump. Unfortunately, by default, only a partial core is
1120 * generated which, in many cases, isn't too useful.
1122 struct sigaction nsa;
1124 sigemptyset(&nsa.sa_mask);
1125 nsa.sa_handler = SIG_DFL;
1126 nsa.sa_flags = SA_FULLDUMP;
1127 sigaction(SIGSEGV, &nsa, NULL);
1128 sigaction(SIGABRT, &nsa, NULL);
1133 ts = cmd_CreateSyntax((char *) 0, WorkerBee, (char *) 0, "tape coordinator");
1134 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset");
1135 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2");
1136 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1137 cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL|CMD_HIDE), "tape device path");
1138 cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL,
1139 "do not query operator for first tape");
1140 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL, "create tickets from KeyFile");
1141 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL|CMD_HIDE), "file to restore to");
1142 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL|CMD_HIDE), "Force multiple XBSA server support");
1144 /* Initialize dirpaths */
1145 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1147 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1149 fprintf(stderr,"Unable to obtain AFS server directory.\n");
1153 /* setup the file paths */
1154 strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TE_PREFIX, NULL);
1155 strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TL_PREFIX, NULL);
1156 strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", CFG_PREFIX, NULL);
1157 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH);
1159 /* special case "no args" case since cmd_dispatch gives help message
1163 ts = (struct cmd_syndesc *) malloc(sizeof(struct cmd_syndesc));
1164 bzero(ts, sizeof(*ts));
1166 ti = (struct cmd_item *) malloc(sizeof(struct cmd_item));
1169 ts->parms[0].items = ti;
1170 ti = (struct cmd_item *) malloc(sizeof(struct cmd_item));
1173 ts->parms[1].items = ti;
1174 ts->parms[2].items = (struct cmd_item *) NULL;
1175 ts->parms[3].items = (struct cmd_item *) NULL;
1176 ts->parms[4].items = (struct cmd_item *) NULL;
1177 ts->parms[5].items = (struct cmd_item *) NULL;
1178 return WorkerBee(ts, (char *) 0);
1181 return cmd_Dispatch(argc, argv);