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 <afsconfig.h>
15 #include <sys/types.h>
19 #include <WINNT/afsevent.h>
21 #include <netinet/in.h>
24 #include <afs/procmgmt.h>
26 #include <afs/afsint.h>
28 #ifdef AFS_PTHREAD_ENV
31 #include <afs/assert.h>
33 #include <afs/prs_fs.h>
36 #include <afs/vlserver.h>
39 #include <afs/afsutil.h>
41 #include <rx/rx_globals.h>
44 #include <afs/cellconfig.h>
46 #include <afs/volser.h>
48 #include <afs/com_err.h>
51 #include <afs/tcdata.h>
52 #include <afs/bubasics.h>
54 #include "error_macros.h"
55 #include <afs/budb_errs.h>
57 #include "butc_xbsa.h"
59 #define N_SECURITY_OBJECTS 3
60 #define ERRCODE_RANGE 8 /* from error_table.h */
62 #define TE_PREFIX "TE"
63 #define TL_PREFIX "TL"
64 #define CFG_PREFIX "CFG"
66 struct ubik_client *cstruct;
67 extern void TC_ExecuteRequest();
68 extern int dbWatcher();
69 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
70 extern struct rx_service *rx_NewService();
71 FILE *logIO, *ErrorlogIO, *centralLogIO, *lastLogIO;
72 char lFile[AFSDIR_PATH_MAX];
74 char ErrorlogFile[256];
75 char lastLogFile[256];
76 char eFile[AFSDIR_PATH_MAX];
77 char tapeConfigFile[AFSDIR_PATH_MAX];
78 char pFile[AFSDIR_PATH_MAX];
80 struct tapeConfig globalTapeConfig;
81 struct deviceSyncNode *deviceLatch;
82 char globalCellName[64];
83 char *whoami = "butc";
85 /* GLOBAL CONFIGURATION PARAMETERS */
96 /* XBSA Global Parameters */
99 struct butx_transactionInfo butxInfo;
101 #define rpc_c_protect_level_default 0
102 afs_uint32 dumpRestAuthnLevel = rpc_c_protect_level_default;
103 char *xbsaObjectOwner;
104 char *appObjectOwner;
105 char *adsmServerName;
115 #define MINGROUPID 0x1
116 #define MAXGROUPID 0x7FFFFFFF
117 afs_int32 statusSize;
119 #define MAXSTATUS 0x7fffffff
120 afs_int32 BufferSize; /* Size in B stored for data */
121 char *centralLogFile;
122 afs_int32 lastLog; /* Log last pass info */
124 /* dummy routine for the audit work. It should do nothing since audits */
125 /* occur at the server level and bos is not a server. */
126 osi_audit() {return 0;}
128 static afs_int32 SafeATOL(anum)
129 register char *anum; {
130 register afs_int32 total;
135 if (tc < '0' || tc > '9') return -1;
144 * Convert a string into an afs_int32.
145 * Returned afs_int32 is in Bytes, Kb, Mb, Gb, or Tb. Based on crunit char.
146 * This routine only converts unsigned float values.
147 * The returned value is a whole number.
149 * numstring - text string to be converted.
150 * crunit - value returned in 'B', 'K', 'M', 'G', 'T'.
151 * ' ' or NULL ==> 'B' (bytes).
153 * number - returned value in requested crunit - rounded
154 * to nearest whole number.
157 * -1 - error in conversion
159 * should deal with signed numbers. Should signal error if no digits
162 atocl(numstring, crunit, number)
164 char crunit; /* Units to report number in */
174 /* Determine which units to report in */
207 count = sscanf(numstring, "%f%c%s", (unsigned char *)&total, &cunit, rest);
208 if ((count > 2) || (count <= 0))
211 cunit = 'B'; /* bytes */
245 /* Go to correct unit */
246 for (; units < runits; units += 3)
248 for (; units > runits; units -= 3)
251 total += 0.5; /* Round up */
252 if ((total > 0x7fffffff) || (total < 0)) /* Don't go over 2G */
259 /* replace last two ocurrences of / by _ */
260 static stringReplace(name)
267 pos = strrchr(name,'/');
270 pos = strrchr(name,'/');
276 static stringNowReplace (logFile, deviceName)
277 char *logFile, *deviceName;
281 char storeDevice[256];
282 int mvFlag = 0, devPrefLen;
284 char devPrefix[] = "\\\\.";
286 char devPrefix[] = "/dev";
289 devPrefLen = strlen(devPrefix);
290 strcpy(storeDevice, deviceName);
291 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
292 deviceName += devPrefLen;
295 while (pos = strchr(deviceName, devPrefix[0])) /* look for / or \ */
297 strcat (logFile, deviceName);
298 /* now put back deviceName to the way it was */
301 deviceName -= devPrefLen;
303 strcpy (deviceName, storeDevice);
310 * get the configuration information for a particular tape device
311 * as specified by the portoffset
313 * filename - full pathname of file containing the tape device
314 * configuration information
315 * config - for return results
316 * portOffset - for which configuration is required
318 * logging not available when this routine is called
319 * caller return value checks
321 * 0 => Found entry with same port, return info in config.
322 * -1 => Error encountered trying to read the file.
323 * 1 => Desired entry does not exist or file does not exist.
327 static afs_int32 GetDeviceConfig(filename, config, portOffset)
329 struct tapeConfig *config;
330 afs_int32 portOffset;
334 char devName[LINESIZE], tcapacity[LINESIZE],
335 tfmsize[LINESIZE], trest[LINESIZE];
339 afs_int32 code=0, count;
341 /* Initialize the config struct */
342 config->capacity = 0;
343 config->fileMarkSize = 0;
344 config->portOffset = portOffset;
345 strcpy(config->device, "");
347 devFile = fopen(filename,"r");
349 if (errno == ENOENT) ERROR_EXIT(1);
350 fprintf(stderr, "Error %d: Can't open %s\n", errno, filename);
354 while ( fgets(line,LINESIZE-1,devFile) ) {
355 count = sscanf(line, "%s %s %s %u%s\n",
356 tcapacity, tfmsize, devName, &aport, trest);
359 if ( atocl(tcapacity, 'K', &capacity) ) {
360 fprintf(stderr, "tapeconfig: Tape capacity parse error in: %s\n", line);
363 if ( atocl(tfmsize, 'B', &fmSize) ) {
364 fprintf(stderr, "tapeconfig: File-mark size parse error in: %s\n", line);
368 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
370 capacity = 0x7fffffff;
373 fprintf(stderr, "tapeconfig: Parse error in: %s\n", line);
378 if ((aport < 0) || (aport > BC_MAXPORTOFFSET)) {
379 fprintf(stderr, "tapeconfig: Port offset parse error in: %s\n", line);
383 if (aport != portOffset)
387 fprintf(stderr, "Invalid file mark size, %d, in: %s\n", fmSize, line);
391 config->capacity = capacity;
392 config->fileMarkSize = fmSize;
393 config->portOffset = aport;
394 strncpy(config->device, devName, 100);
399 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
403 if (devFile) fclose(devFile);
409 static afs_int32 GetConfigParams(filename, port)
415 char line[LINESIZE], cmd[LINESIZE], value[LINESIZE];
419 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
420 dump_namecheck = 1; /* check tape name on dumps */
421 queryoperator = 1; /* can question operator */
422 autoQuery = 1; /* prompt for first tape */
423 isafile = 0; /* Do not dump to a file */
424 opencallout = (char *)0; /* open callout routine */
425 closecallout = (char *)0; /* close callout routine */
426 tapemounted = 0; /* tape is not mounted */
428 BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE);
429 dumpRestAuthnLevel = rpc_c_protect_level_default;
430 xbsaObjectOwner = (char *)0; /* bsaObjectOwner */
431 appObjectOwner = (char *)0; /* appObjectOwner */
432 adsmServerName = (char *)0; /* TSM server name - same as ADSM */
433 xbsaSecToken = (char *)0; /* XBSA sercurity token */
434 xbsalGName = (char *)0; /* XBSA IGName */
436 BufferSize = BUTM_BLOCKSIZE;
438 centralLogFile = (char *)0; /* Log for all butcs */
439 centralLogIO = 0; /* Log for all butcs */
440 statusSize = 0; /* size before status message */
441 maxpass = PASSESDFLT; /* dump passes */
442 lastLog = 0; /* separate log for last pass */
443 lastLogIO = 0; /* separate log for last pass */
444 groupId = 0; /* Group id for multiple dumps */
446 /* Try opening the CFG_<port> file */
447 sprintf(paramFile, "%s_%d", filename, port);
448 devFile = fopen(paramFile, "r");
450 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
451 sprintf(logFile, "%s_%d", lFile, port);
452 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
453 sprintf(ErrorlogFile, "%s_%d", eFile, port);
454 } else if (CONF_XBSA) {
455 /* If configured as XBSA, a configuration file CFG_<port> must exist */
456 printf("Cannot open configuration file %s", paramFile);
459 /* Try the CFG_<device> name as the device file */
460 strcpy(paramFile, filename);
461 stringNowReplace(paramFile, globalTapeConfig.device);
462 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
463 strcpy(logFile,lFile);
464 stringNowReplace(logFile,globalTapeConfig.device);
465 strcpy(lastLogFile,lFile);
466 stringNowReplace(lastLogFile,globalTapeConfig.device);
467 strcat(lastLogFile, ".lp");
468 strcpy(ErrorlogFile,eFile);
469 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
471 /* Now open the device file */
472 devFile = fopen(paramFile, "r");
474 ERROR_EXIT(0);/* CFG file doesn't exist for non-XBSA and that's ok */
477 /* Read each line of the Configuration file */
478 while (fgets(line,LINESIZE-1,devFile)) {
479 cnt = sscanf(line, "%s %s", cmd, value);
483 printf("Bad line in %s: %s\n", paramFile, line);
487 for (cnt=0; cnt<strlen(cmd); cnt++)
488 if (islower(cmd[cnt])) cmd[cnt] = toupper(cmd[cnt]);
490 if (!strcmp(cmd,"NAME_CHECK"))
493 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
497 for (cnt=0; cnt<strlen(value); cnt++)
498 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
500 if (!strcmp(value,"NO"))
502 printf("Dump tape name check is disabled\n");
507 printf("Dump tape name check is enabled\n");
512 else if (!strcmp(cmd,"MOUNT"))
515 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
519 opencallout = (char*)malloc(strlen(value)+1);
520 strcpy(opencallout, value);
521 printf("Tape mount callout routine is %s\n", opencallout);
524 else if (!strcmp(cmd,"UNMOUNT"))
527 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
531 closecallout = (char*)malloc(strlen(value)+1);
532 strcpy(closecallout, value);
533 printf("Tape unmount callout routine is %s\n", closecallout);
536 else if (!strcmp(cmd,"ASK"))
538 for (cnt=0; cnt<strlen(value); cnt++)
539 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
541 if (!strcmp(value,"NO"))
543 printf("Operator queries are disabled\n");
548 printf("Operator queries are enabled\n");
553 else if (!strcmp(cmd,"FILE"))
556 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
560 for (cnt=0; cnt<strlen(value); cnt++)
561 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
563 if (!strcmp(value,"YES"))
565 printf("Will dump to a file\n");
570 printf("Will not dump to a file\n");
575 else if (!strcmp(cmd,"AUTOQUERY"))
578 printf("Warning: The %s parameter is ignored with a Backup Service\n", cmd);
582 for (cnt=0; cnt<strlen(value); cnt++)
583 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
585 if (!strcmp(value,"NO"))
587 printf("Auto query is disabled\n");
592 printf("Auto query is enabled\n");
597 else if (!strcmp(cmd,"BUFFERSIZE"))
600 afs_int32 tapeblocks;
603 if ( atocl(value, 'K', &size) ) {
604 fprintf(stderr, "BUFFERSIZE parse error\n");
608 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
609 * determine BufferSize needed for that many tapeblocks.
611 tapeblocks = size / 16;
612 if (tapeblocks <= 0) tapeblocks = 1;
613 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks*16));
614 BufferSize = tapeblocks * BUTM_BLOCKSIZE;
617 if ( atocl(value, 'B', &size) ) {
618 fprintf(stderr, "BUFFERSIZE parse error\n");
621 if (size < XBSAMINBUFFER) size = XBSAMINBUFFER;
622 if (size > XBSAMAXBUFFER) size = XBSAMAXBUFFER;
623 printf("XBSA buffer size is %u Bytes\n", size);
633 /* All the xbsa spacific parameters */
634 else if (!strcmp(cmd,"TYPE") || !strcmp(cmd,"NODE") ||
635 !strcmp(cmd,"SERVER") || !strcmp(cmd,"PASSWORD") ||
636 !strcmp(cmd,"PASSFILE") || !strcmp(cmd,"MGMTCLASS"))
638 printf("This binary does not have XBSA support\n");
642 else if (!strcmp(cmd,"TYPE")) /* required for XBSA */
645 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
649 for (cnt=0; (size_t)cnt<strlen(value); cnt++)
650 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
652 if (strcmp(value,"TSM") == 0) {
653 xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */
655 printf("Configuration file error, %s %s is not recognized\n", cmd, value);
656 xbsaType = XBSA_SERVER_TYPE_UNKNOWN;
658 printf("XBSA type is %s\n",
659 ((xbsaType == XBSA_SERVER_TYPE_UNKNOWN)?"Unknown":value));
662 else if (!strcmp(cmd,"NODE"))
665 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
668 xbsaObjectOwner = malloc(strlen(value)+1);
669 strcpy(xbsaObjectOwner, value);
670 printf("XBSA node is %s\n", xbsaObjectOwner);
673 else if (!strcmp(cmd,"SERVER")) /* required for XBSA */
676 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
679 adsmServerName = malloc(strlen(value)+1);
680 strcpy(adsmServerName, value);
681 printf("XBSA server is %s\n", adsmServerName);
684 else if (!strcmp(cmd,"PASSWORD")) /* This or PASSFILE required for XBSA */
687 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
691 printf("Warning: The %s parameter is ignored. Already read password\n", cmd);
695 xbsaSecToken = malloc(strlen(value)+1);
696 strcpy(xbsaSecToken, value);
697 printf("XBSA Password has been read\n");
700 else if (!strcmp(cmd,"PASSFILE")) /* This or PASSWORD required for XBSA */
704 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
708 printf("Warning: The %s parameter is ignored. Already read password\n", cmd);
712 pwdFile = fopen(value,"r");
714 printf("Configuration file error, cannot open password file %s\n", value);
717 xbsaSecToken = malloc(LINESIZE);
718 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
719 printf("Configuration file error, cannot read password file %s\n", value);
722 printf("XBSA password retrieved from password file\n");
725 else if (!strcmp(cmd,"MGMTCLASS")) /* XBSA */
728 printf("Warning: The %s parameter is ignored with a tape drive\n", cmd);
731 xbsalGName = malloc(strlen(value)+1);
732 strcpy(xbsalGName, value);
733 printf("XBSA management class is %s\n", xbsalGName);
737 else if (!strcmp(cmd,"MAXPASS"))
739 maxpass = SafeATOL(value);
740 if (maxpass < PASSESMIN) maxpass = PASSESMIN;
741 if (maxpass > PASSESMAX) maxpass = PASSESMAX;
742 printf("MAXPASS is %d\n", maxpass);
745 else if (!strcmp(cmd,"GROUPID"))
747 groupId = SafeATOL(value);
748 if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) {
749 printf("Configuration file error, %s %s is invalid\n", cmd, value);
752 printf("Group Id is %d\n", groupId);
755 else if (!strcmp(cmd,"LASTLOG"))
757 for (cnt=0; (size_t)cnt<strlen(value); cnt++)
758 if (islower(value[cnt])) value[cnt] = toupper(value[cnt]);
760 lastLog = (strcmp(value,"YES") == 0);
761 printf("Will %sgenerate a last log\n", (lastLog?"":"not "));
764 else if (!strcmp(cmd,"CENTRALLOG"))
766 centralLogFile = malloc(strlen(value)+1);
767 strcpy(centralLogFile, value);
768 printf("Central log file is %s\n", centralLogFile);
771 else if (!strcmp(cmd,"STATUS"))
773 if (atocl(value, 'B', &statusSize)) {
774 fprintf(stderr, "STATUS parse error\n");
777 if (statusSize < MINSTATUS) statusSize = MINSTATUS;
778 if (statusSize > MAXSTATUS) statusSize = MAXSTATUS;
782 printf("Warning: Unrecognized configuration parameter: %s", line);
787 /* Statussize is in bytes and requires that BufferSize be set first */
788 statusSize *= BufferSize;
789 if (statusSize < 0) statusSize = 0x7fffffff; /*max size*/
790 printf("Status every %ld Bytes\n", statusSize);
794 if (devFile) fclose(devFile);
796 /* If the butc is configured as XBSA, check for required parameters */
798 if (!code && CONF_XBSA) {
799 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
800 printf("Configuration file error, the TYPE parameter must be specified, or\n");
801 printf("an entry must exist in %s for port %d\n", tapeConfigFile, port);
804 if (!adsmServerName) {
805 printf("Configuration file error, the SERVER parameter must be specified\n");
809 printf("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
817 static WorkerBee(as, arock)
818 struct cmd_syndesc *as;
821 register afs_int32 code;
822 struct rx_securityClass *(securityObjects[3]);
823 struct rx_service *service;
824 struct ktc_token ttoken;
827 /*process arguments */
828 afs_int32 portOffset = 0;
830 #ifdef AFS_PTHREAD_ENV
831 pthread_t dbWatcherPid;
832 pthread_attr_t tattr;
835 PROCESS dbWatcherPid;
840 /*initialize the error tables */
841 initialize_ka_error_table();
842 initialize_rxk_error_table();
843 initialize_ktc_error_table();
844 initialize_acfg_error_table();
845 initialize_cmd_error_table();
846 initialize_vl_error_table();
847 initialize_butm_error_table();
848 initialize_butc_error_table();
850 initialize_butx_error_table();
852 initialize_vols_error_table();
853 initialize_budb_error_table();
854 initialize_bucd_error_table();
856 if (as->parms[0].items)
858 portOffset = SafeATOL(as->parms[0].items->data);
859 if (portOffset == -1)
861 fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data);
864 else if (portOffset > BC_MAXPORTOFFSET)
866 fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET);
871 xbsaType = XBSA_SERVER_TYPE_NONE; /* default */
872 if (as->parms[3].items) { /* -device */
873 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
874 globalTapeConfig.fileMarkSize = 0;
875 globalTapeConfig.portOffset = portOffset;
876 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
877 xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */
879 /* Search for an entry in tapeconfig file */
880 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
882 fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile);
885 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
886 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
888 xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE);
891 if (as->parms[6].items) { /* -restoretofile */
892 int s = strlen(as->parms[6].items->data);
893 restoretofile = malloc(s+1);
894 strncpy(restoretofile, as->parms[6].items->data, s+1);
895 printf("Restore to file '%s'\n", restoretofile);
898 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
899 * the exact xbsaType within the call (won't be unknown) - double check.
901 code = GetConfigParams(pFile, portOffset);
902 if (code) exit(code);
904 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) {
905 printf("\nConfiguration file error, the TYPE parameter must be specified, or\n");
906 printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset);
910 /* Not compiled for XBSA code so we can't support it */
912 printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset);
913 printf("This binary does not have XBSA support\n");
918 /* Open the log files. The pathnames were set in GetConfigParams() */
919 logIO = fopen(logFile,"a");
921 fprintf(stderr,"Failed to open %s\n",logFile);
924 ErrorlogIO = fopen(ErrorlogFile,"a");
926 fprintf(stderr,"Failed to open %s\n",ErrorlogFile);
930 lastLogIO = fopen(lastLogFile,"a");
932 fprintf(stderr,"Failed to open %s\n", lastLogFile);
936 if (centralLogFile) {
939 char path[AFSDIR_PATH_MAX];
941 statcode = stat(centralLogFile, &sbuf);
942 centralLogIO = fopen(centralLogFile,"a");
944 fprintf(stderr,"Failed to open %s; error %d\n",centralLogFile, errno);
949 /* Make sure it is not in AFS, has to have been created first */
950 if (!realpath(centralLogFile, path)) {
951 fprintf(stderr,"Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno);
953 if (strncmp(path,"/afs/",5) == 0) {
954 fprintf(stderr,"The central log '%s' should not be in AFS\n", centralLogFile);
960 /* Write header if created it */
962 char *h1="TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
963 char *h2="----- ------------------- ------------------- -------- ---------\n";
964 /* File didn't exist before so write the header lines */
965 fwrite(h1, strlen(h1), 1, centralLogIO);
966 fwrite(h2, strlen(h2), 1, centralLogIO);
967 fflush(centralLogIO);
971 if (as->parms[1].items)
973 debugLevel = SafeATOL(as->parms[1].items->data);
976 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
982 /* Setup XBSA library interface */
985 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
986 if (rc != XBSA_SUCCESS) {
987 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
991 forcemultiple = (as->parms[7].items ? 1 : 0); /*-xbsaforcemultiple */
993 printf("Force XBSA multiple server support\n");
995 rc = InitToServer(0/*taskid*/, &butxInfo, adsmServerName);
996 if (rc != XBSA_SUCCESS) return(1);
1001 if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
1002 else cellName[0] = '\0';
1004 if (as->parms[4].items) autoQuery = 0;
1006 localauth = (as->parms[5].items ? 1 : 0);
1008 code = rx_Init(htons(BC_TAPEPORT + portOffset));
1011 TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset);
1014 rx_SetRxDeadTime(150);
1016 /* Establish connection with the vldb server */
1017 code = vldbClientInit(0, localauth, cellName, &cstruct, &ttoken);
1020 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1024 strcpy(globalCellName, cellName);
1026 /*initialize the dumpNode list */
1027 InitNodeList(portOffset);
1029 deviceLatch = (struct deviceSyncNode *)(malloc (sizeof(struct deviceSyncNode)));
1030 Lock_Init(&(deviceLatch->lock));
1031 deviceLatch->flags = 0;
1033 /* initialize database support, volume support, and logs */
1035 /* Create a single security object, in this case the null security
1036 * object, for unauthenticated connections, which will be used to control
1037 * security on connections made to this server
1040 securityObjects[0] = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
1041 securityObjects[1] = (struct rx_securityClass *) 0; /* don't bother with rxvab */
1042 if ( !securityObjects[0] )
1044 TLog(0, "rxnull_NewServerSecurityObject");
1048 service = rx_NewService(0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest);
1051 TLog(0, "rx_NewService");
1054 rx_SetMaxProcs(service, 4);
1056 /* Establish connection to the backup database */
1057 code = udbClientInit(0, localauth, cellName);
1060 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1063 /* This call is here to verify that we are authentiated.
1064 * The call does nothing and will return BUDB_NOTPERMITTED
1065 * if we don't belong.
1067 code = bcdb_deleteDump(0,0,0,0);
1068 if (code == BUDB_NOTPERMITTED) {
1069 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1074 #ifdef AFS_PTHREAD_ENV
1075 code = pthread_attr_init(&tattr);
1078 TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task");
1081 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1084 TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task");
1088 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1089 AFS_SIGSET_RESTORE();
1091 code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, 2, "dbWatcher", &dbWatcherPid);
1095 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1099 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1100 portOffset, debugLevel);
1101 TLog(0, "Token expires: %s\n", cTIME(&ttoken.endTime));
1103 rx_StartServer(1); /* Donate this process to the server process pool */
1104 TLog(0, "Error: StartServer returned");
1108 #ifndef AFS_NT40_ENV
1109 #include "AFS_component_version_number.c"
1116 register struct cmd_syndesc *ts;
1117 register struct cmd_item *ti;
1119 #ifdef AFS_AIX32_ENV
1121 * The following signal action for AIX is necessary so that in case of a
1122 * crash (i.e. core is generated) we can include the user's data section
1123 * in the core dump. Unfortunately, by default, only a partial core is
1124 * generated which, in many cases, isn't too useful.
1126 struct sigaction nsa;
1128 sigemptyset(&nsa.sa_mask);
1129 nsa.sa_handler = SIG_DFL;
1130 nsa.sa_flags = SA_FULLDUMP;
1131 sigaction(SIGSEGV, &nsa, NULL);
1132 sigaction(SIGABRT, &nsa, NULL);
1137 ts = cmd_CreateSyntax((char *) 0, WorkerBee, (char *) 0, "tape coordinator");
1138 cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset");
1139 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2");
1140 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1141 cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL|CMD_HIDE), "tape device path");
1142 cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL,
1143 "do not query operator for first tape");
1144 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL, "create tickets from KeyFile");
1145 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL|CMD_HIDE), "file to restore to");
1146 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL|CMD_HIDE), "Force multiple XBSA server support");
1148 /* Initialize dirpaths */
1149 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
1151 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1153 fprintf(stderr,"Unable to obtain AFS server directory.\n");
1157 /* setup the file paths */
1158 strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TE_PREFIX, NULL);
1159 strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TL_PREFIX, NULL);
1160 strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", CFG_PREFIX, NULL);
1161 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH);
1163 /* special case "no args" case since cmd_dispatch gives help message
1167 ts = (struct cmd_syndesc *) malloc(sizeof(struct cmd_syndesc));
1168 bzero(ts, sizeof(*ts));
1170 ti = (struct cmd_item *) malloc(sizeof(struct cmd_item));
1173 ts->parms[0].items = ti;
1174 ti = (struct cmd_item *) malloc(sizeof(struct cmd_item));
1177 ts->parms[1].items = ti;
1178 ts->parms[2].items = (struct cmd_item *) NULL;
1179 ts->parms[3].items = (struct cmd_item *) NULL;
1180 ts->parms[4].items = (struct cmd_item *) NULL;
1181 ts->parms[5].items = (struct cmd_item *) NULL;
1182 return WorkerBee(ts, (char *) 0);
1185 return cmd_Dispatch(argc, argv);