void softsig_init(void) { int rc; AFS_SIGSET_DECL; AFS_SIGSET_CLEAR(); rc = pthread_create(&softsig_tid, NULL, &softsig_thread, NULL); assert(0 == rc); AFS_SIGSET_RESTORE(); signal (SIGUSR1, softsig_usr1); }
/* * Start an Rx server process. */ void rxi_StartServerProc(void *(*proc) (void *), int stacksize) { pthread_t thread; pthread_attr_t tattr; AFS_SIGSET_DECL; if (pthread_attr_init(&tattr) != 0) { osi_Panic("Unable to Create Rx server thread (pthread_attr_init)\n"); } if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) != 0) { osi_Panic("Unable to Create Rx server thread (pthread_attr_setdetachstate)\n"); } /* * NOTE: We are ignoring the stack size parameter, for now. */ AFS_SIGSET_CLEAR(); if (pthread_create(&thread, &tattr, server_entry, (void *)proc) != 0) { osi_Panic("Unable to Create Rx server thread\n"); } AFS_SIGSET_RESTORE(); }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code; struct rx_securityClass *(securityObjects[3]); struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif afs_uint32 host = htonl(INADDR_ANY); debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ int s = strlen(as->parms[6].items->data); restoretofile = malloc(s + 1); strncpy(restoretofile, as->parms[6].items->data, s + 1); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char path[AFSDIR_PATH_MAX]; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ if (!realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode))); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* Create a single security object, in this case the null security * object, for unauthenticated connections, which will be used to control * security on connections made to this server */ securityObjects[0] = rxnull_NewServerSecurityObject(); securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */ if (!securityObjects[0]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } service = rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }
/* STC_DeleteDump */ afs_int32 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId) { afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */ #ifdef xbsa struct deleteDumpIf *ptr = 0; statusP statusPtr = 0; #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif #endif *taskId = 0; if (!CONF_XBSA) return (TC_BADTASK); /* Only do if butc is started as XBSA */ #ifdef xbsa code = 0; if (callPermitted(acid) == 0) return (TC_NOTPERMITTED); ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr)); if (!ptr) ERROR_EXIT(TC_NOMEMORY); *taskId = allocTaskId(); ptr->dumpID = dumpID; ptr->taskId = *taskId; statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = *taskId; statusPtr->lastPolled = time(0); statusPtr->flags &= ~STARTING; strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName)); unlock_Status(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, DeleteDump, ptr); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); if (ptr) free(ptr); } #endif /* xbsa */ return (code); }
afs_int32 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId) { #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif struct scanTapeIf *ptr; statusP statusPtr = NULL; afs_int32 code = 0; #ifdef xbsa if (CONF_XBSA) return (TC_BADTASK); /* ScanDumps does not apply if XBSA */ #endif if (callPermitted(acid) == 0) return (TC_NOTPERMITTED); *taskId = allocTaskId(); ptr = (struct scanTapeIf *)malloc(sizeof(*ptr)); if (!ptr) ERROR_EXIT(TC_NOMEMORY); ptr->addDbFlag = addDbFlag; ptr->taskId = *taskId; /* create the status node */ statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = *taskId; statusPtr->lastPolled = time(0); statusPtr->flags &= ~STARTING; /* ok to examine */ strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName)); unlock_Status(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, ScanDumps, ptr); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); if (ptr) free(ptr); } return code; }
afs_int32 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId) { #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif statusP statusPtr = NULL; afs_int32 code = 0; struct saveDbIf *ptr; #ifdef xbsa if (CONF_XBSA) return (TC_BADTASK); /* LabelTape does not apply if XBSA */ #endif if (callPermitted(rxCall) == 0) return (TC_NOTPERMITTED); *taskId = allocTaskId(); ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf)); if (!ptr) ERROR_EXIT(TC_NOMEMORY); ptr->archiveTime = archiveTime; ptr->taskId = *taskId; /* create the status node */ statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = *taskId; statusPtr->lastPolled = time(0); statusPtr->flags &= ~STARTING; /* ok to examine */ strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName)); unlock_Status(); ptr->statusPtr = statusPtr; #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, saveDbToTape, ptr); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); if (ptr) free(ptr); } return (code); }
afs_int32 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId) { #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif statusP statusPtr; afs_int32 code = 0; #ifdef xbsa if (CONF_XBSA) return (TC_BADTASK); /* LabelTape does not apply if XBSA */ #endif if (callPermitted(rxCall) == 0) return (TC_NOTPERMITTED); *taskId = allocTaskId(); /* create the status node */ statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = *taskId; statusPtr->flags &= ~STARTING; /* ok to examine */ statusPtr->lastPolled = time(0); strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName)); unlock_Status(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId, "Db restore", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); } return (code); }
afs_int32 STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID) { struct dumpNode *newNode; statusP statusPtr; afs_int32 code = 0; #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif if (callPermitted(acid) == 0) return (TC_NOTPERMITTED); /* should verify parameter validity */ /* this creates a node in list, alots an id for it and prepares it for locking */ CreateNode(&newNode); newNode->restores = (struct tc_restoreDesc *) malloc(sizeof(struct tc_restoreDesc) * arestores->tc_restoreArray_len); newNode->arraySize = arestores->tc_restoreArray_len; CopyRestoreDesc(newNode->restores, arestores); *taskID = newNode->taskID; /* should log the intent */ /* create the status node */ statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = newNode->taskID; statusPtr->flags &= ~STARTING; /* ok to examine */ statusPtr->lastPolled = time(0); strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName)); unlock_Status(); newNode->statusNodePtr = statusPtr; /* create the LWP to do the real work behind the scenes */ #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, Restorer, newNode); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode, "restorer process", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */ } return (code); }
afs_int32 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId) { struct dumpNode *newNode = 0; statusP statusPtr = 0; #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif afs_int32 code = 0; if (callPermitted(rxCallId) == 0) return (TC_NOTPERMITTED); /* should be verifying parameter validity */ *taskId = 0; /* this creates a node in list, alots an id for it and prepares it for locking */ CreateNode(&newNode); /*set up the parameters in the node, to be used by LWP */ strcpy(newNode->dumpSetName, tcdiPtr->dumpName); newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1); strcpy(newNode->dumpName, tcdiPtr->dumpPath); newNode->volumeSetName = (char *)malloc(strlen(tcdiPtr->volumeSetName) + 1); strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName); CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet); newNode->dumps = (struct tc_dumpDesc *) malloc(sizeof(struct tc_dumpDesc) * tc_dumpArrayPtr->tc_dumpArray_len); newNode->arraySize = tc_dumpArrayPtr->tc_dumpArray_len; CopyDumpDesc(newNode->dumps, tc_dumpArrayPtr); newNode->parent = tcdiPtr->parentDumpId; newNode->level = tcdiPtr->dumpLevel; newNode->doAppend = tcdiPtr->doAppend; #ifdef xbsa if (CONF_XBSA) newNode->doAppend = 0; /* Append flag is ignored if talking to XBSA */ #endif /* create the status node */ statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = newNode->taskID; statusPtr->lastPolled = time(0); statusPtr->flags &= ~STARTING; /* ok to examine */ strncpy(statusPtr->taskName, "Dump", sizeof(statusPtr->taskName)); unlock_Status(); newNode->statusNodePtr = statusPtr; /* create the LWP to do the real work behind the scenes */ #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, Dumper, newNode); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process", &pid); #endif if (code) ERROR_EXIT(code); *taskId = newNode->taskID; error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */ } return (code); }
afs_int32 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId) { #ifdef AFS_PTHREAD_ENV pthread_t pid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS pid; #endif struct labelTapeIf *ptr; statusP statusPtr = NULL; afs_int32 code; #ifdef xbsa if (CONF_XBSA) return (TC_BADTASK); /* LabelTape does not apply if XBSA */ #endif if (callPermitted(acid) == 0) return (TC_NOTPERMITTED); ptr = (struct labelTapeIf *)malloc(sizeof(*ptr)); if (!ptr) ERROR_EXIT(TC_NOMEMORY); memcpy(&ptr->label, label, sizeof(ptr->label)); /* set up the status node */ *taskId = allocTaskId(); /* for bucoord */ ptr->taskId = *taskId; statusPtr = createStatusNode(); if (!statusPtr) ERROR_EXIT(TC_INTERNALERROR); lock_Status(); statusPtr->taskId = *taskId; statusPtr->lastPolled = time(0); statusPtr->flags &= ~STARTING; /* ok to examine */ strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName)); unlock_Status(); /* create the LWP to do the real work behind the scenes */ #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) ERROR_EXIT(code); code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) ERROR_EXIT(code); AFS_SIGSET_CLEAR(); code = pthread_create(&pid, &tattr, Labeller, ptr); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process", &pid); #endif error_exit: if (code) { if (statusPtr) deleteStatusNode(statusPtr); if (ptr) free(ptr); } return (code); }
static int writeDbDump(struct butm_tapeInfo *tapeInfoPtr, afs_uint32 taskId, Date expires, afs_uint32 dumpid) { afs_int32 blockSize; afs_int32 writeBufNbytes = 0; char *writeBlock = 0; char *writeBuffer = 0; char *writeBufPtr; afs_int32 transferSize; char *readBufPtr = NULL; afs_int32 maxReadSize; charListT charList; afs_int32 done; afs_int32 code; afs_int32 chunksize = 0; afs_int32 tc_EndMargin, tc_KEndMargin, kRemaining; int sequence; int wroteLabel; int firstcall; #ifdef AFS_PTHREAD_ENV pthread_t alivePid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS alivePid; #endif extern struct tapeConfig globalTapeConfig; extern struct udbHandleS udbHandle; blockSize = BUTM_BLKSIZE; writeBlock = (char *)malloc(BUTM_BLOCKSIZE); if (!writeBlock) ERROR_EXIT(TC_NOMEMORY); writeBuffer = writeBlock + sizeof(struct blockMark); memset(writeBuffer, 0, BUTM_BLKSIZE); maxReadSize = 1024; /* * The margin of space to check for end of tape is set to the * amount of space used to write an end-of-tape multiplied by 2. * The amount of space is size of a 16K EODump marker, its EOF * marker, and up to two EOF markers done on close (1 16K blocks + * 3 EOF * markers). */ tc_EndMargin = (16384 + 3 * globalTapeConfig.fileMarkSize) * 2; tc_KEndMargin = tc_EndMargin / 1024; /* have to write enclose the dump in file marks */ code = butm_WriteFileBegin(tapeInfoPtr); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write FileBegin on tape\n"); ERROR_EXIT(code); } writeBufPtr = &writeBuffer[0]; firstcall = 1; sequence = 1; charList.charListT_val = 0; charList.charListT_len = 0; while (1) { /*w */ /* When no data in buffer, read data from the budb_server */ if (charList.charListT_len == 0) { /* get more data. let rx allocate space */ if (charList.charListT_val) { free(charList.charListT_val); charList.charListT_val = 0; } /* get the data */ code = ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client, UF_SINGLESERVER, firstcall, maxReadSize, &charList, &done); if (code) { ErrorLog(0, taskId, code, 0, "Can't read database\n"); ERROR_EXIT(code); } /* If this if the first call to the budb server, create a thread * that will keep the connection alive (during tape changes). */ if (firstcall) { #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { ErrorLog(0, taskId, code, 0, "Can't pthread_attr_init Keep-alive process\n"); ERROR_EXIT(code); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { ErrorLog(0, taskId, code, 0, "Can't pthread_attr_setdetachstate Keep-alive process\n"); ERROR_EXIT(code); } AFS_SIGSET_CLEAR(); code = pthread_create(&alivePid, &tattr, KeepAlive, 0); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(KeepAlive, 16384, 1, (void *)NULL, "Keep-alive process", &alivePid); #endif /* XXX should we check code here ??? XXX */ } firstcall = 0; readBufPtr = charList.charListT_val; } if ((charList.charListT_len == 0) && done) break; /* compute how many bytes and transfer to the write Buffer */ transferSize = (charList.charListT_len < (blockSize - writeBufNbytes)) ? charList.charListT_len : (blockSize - writeBufNbytes); memcpy(writeBufPtr, readBufPtr, transferSize); charList.charListT_len -= transferSize; writeBufPtr += transferSize; readBufPtr += transferSize; writeBufNbytes += transferSize; /* If filled the write buffer, then write it to tape */ if (writeBufNbytes == blockSize) { code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write data on tape\n"); ERROR_EXIT(code); } memset(writeBuffer, 0, blockSize); writeBufPtr = &writeBuffer[0]; writeBufNbytes = 0; /* Every BIGCHUNK bytes check if aborted */ chunksize += blockSize; if (chunksize > BIGCHUNK) { chunksize = 0; if (checkAbortByTaskId(taskId)) ERROR_EXIT(TC_ABORTEDBYREQUEST); } /* * check if tape is full - since we filled a blockSize worth of data * assume that there is more data. */ kRemaining = butm_remainingKSpace(tapeInfoPtr); if (kRemaining < tc_KEndMargin) { code = butm_WriteFileEnd(tapeInfoPtr); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write FileEnd on tape\n"); ERROR_EXIT(code); } code = butm_WriteEOT(tapeInfoPtr); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write end-of-dump on tape\n"); ERROR_EXIT(code); } /* Mark tape as having been written */ tapeEntryPtr->useKBytes = tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0); tapeEntryPtr->flags = BUDB_TAPE_WRITTEN; unmountTape(taskId, tapeInfoPtr); /* Get next tape and writes its label */ sequence++; code = GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, 1, &wroteLabel); if (code) ERROR_EXIT(code); code = butm_WriteFileBegin(tapeInfoPtr); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write FileBegin on tape\n"); ERROR_EXIT(code); } } } } /*w */ /* no more data to be read - if necessary, flush out the last buffer */ if (writeBufNbytes > 0) { code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize); if (code) { ErrorLog(1, taskId, code, tapeInfoPtr->error, "Can't write data on tape\n"); ERROR_EXIT(code); } } code = butm_WriteFileEnd(tapeInfoPtr); if (code) { ErrorLog(0, taskId, code, tapeInfoPtr->error, "Can't write FileEnd on tape\n"); ERROR_EXIT(code); } /* Mark tape as having been written */ tapeEntryPtr->useKBytes = tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0); tapeEntryPtr->flags = BUDB_TAPE_WRITTEN; error_exit: /* Let the KeepAlive process stop on its own */ code = ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client, UF_END_SINGLESERVER, 0); if (writeBlock) free(writeBlock); if (charList.charListT_val) free(charList.charListT_val); return (code); }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code, numClasses; struct rx_securityClass *(nullObjects[1]), **secObjs, **allObjs; struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif char hoststr[16]; afs_uint32 host = htonl(INADDR_ANY); char *auditFileName = NULL; char *auditInterface = NULL; debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ restoretofile = strdup(as->parms[6].items->data); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char *path; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ path = malloc(AFSDIR_PATH_MAX); if (path == NULL || !realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } free(path); #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } /* Open the configuration directory */ butc_confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (butc_confdir == NULL) { TLog(0, "Failed to open server configuration directory"); exit(1); } /* Start auditing */ osi_audit_init(); if (as->parms[9].items) { auditFileName = as->parms[9].items->data; } if (auditFileName != NULL) osi_audit_file(auditFileName); if (as->parms[10].items) { auditInterface = as->parms[10].items->data; if (osi_audit_interface(auditInterface)) { TLog(0, "Invalid audit interface '%s'\n", auditInterface); exit(1); } } osi_audit(TC_StartEvent, 0, AUD_END); osi_audit_set_user_check(butc_confdir, tc_IsLocalRealmMatch); if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); (void)signal(SIGINT, xbsa_shutdown); (void)signal(SIGHUP, xbsa_shutdown); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); allow_unauth = (as->parms[11].items ? 1 : 0); if (!allow_unauth && !localauth) { const char *errstr = "Neither -localauth nor -allow_unauthenticated was provided; refusing to start in unintended insecure configuration\n"; TLog(0, "%s", (char *)errstr); exit(1); } if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } TLog(0, "butc binding rx to %s:%d\n", afs_inet_ntoa_r(host, hoststr), BC_TAPEPORT + portOffset); code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = malloc(sizeof(struct deviceSyncNode)); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* * Create security objects for the Rx server functionality. Historically * this was a single rxnull security object, since the tape controller was * run by an operator that had local access to the tape device and some * administrative privilege in the cell (to be able to perform volume-level * accesses), but on a machine that was not necessarily trusted to hold the * cell-wide key. * * Such a configuration is, of course, insecure because anyone can make * inbound RPCs and manipulate the database, including creating bogus * dumps and restoring them! Additionally, in modern usage, butc is * frequently run with -localauth to authenticate its outbound connections * to the volservers and budb with the cell-wide key, in which case the * cell-wide key is present and could be used to authenticate incoming * connections as well. * * If -localauth is in use, create the full barrage of server security * objects, including rxkad, so that inbound connections can be verified * to only be made by authenticated clients. Otherwise, only the rxnull * class is in use with a single server security object. Note that butc * will refuse to start in this configuration unless the * "-allow_unauthenticated" flag is provided, indicating that the operator * has ensured that incoming connections are appropriately restricted by * firewall configuration or network topology. */ if (allow_unauth) { nullObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject(); if (!nullObjects[RX_SECIDX_NULL]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } numClasses = 1; secObjs = nullObjects; } else { /* Must be -localauth, so the cell keys are available. */ afsconf_BuildServerSecurityObjects(butc_confdir, &allObjs, &numClasses); secObjs = allObjs; } service = rx_NewServiceHost(host, 0, 1, "BUTC", secObjs, numClasses, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }