void rxi_StartListener(void) { /* Priority of listener should be high, so it can keep conns alive */ #define RX_LIST_STACK 24000 LWP_CreateProcess(rx_ListenerProc, RX_LIST_STACK, LWP_MAX_PRIORITY, NULL, "rx_Listener", &rx_listenerPid); if (registerProgram) (*registerProgram) (rx_listenerPid, "listener"); }
static int putMrSleeptoBed(void) { PROCESS mrsleepy; if (LWP_CreateProcess (MrSleepy, LWPTEST_STACKSIZE, 1, NULL, "mrsleepy", &mrsleepy)) errx (1, "Cannot create consumer process"); return 0; }
static void MakeClients(void) { int i; char thisname[20]; PROCESS thispid; for (i = 0; i < Clients; i++) { sprintf(thisname, "Client%02d", i); LWP_CreateProcess(ClientBody, 16384, LWP_NORMAL_PRIORITY, NULL, thisname, &thispid); } }
static void MakeWorkers(void) { int i; char thisname[20]; PROCESS thispid; for (i = 0; i < Workers; i++) { sprintf(thisname, "Worker%02d", i); LWP_CreateProcess(WorkerBody, 16384, LWP_NORMAL_PRIORITY, NULL, thisname, &thispid); } }
int ropa_init (unsigned num_cb, unsigned num_cli, unsigned num_cc, unsigned hashsz_cb, unsigned hashsz_cli, unsigned hashsz_cc) { ht_callbacks = hashtabnew (hashsz_cb, callbacks_cmp, callbacks_hash); if (ht_callbacks == NULL) errx (1, "ropa_init: failed to create hashtable for callbacks"); ht_clients_ip = hashtabnew (hashsz_cli, clients_cmp_ip, clients_hash_ip); if (ht_clients_ip == NULL) errx (1, "ropa_init: failed to create hashtable for clients_ip"); ht_clients_uuid = hashtabnew (hashsz_cli, clients_cmp_uuid, clients_hash_uuid); if (ht_clients_uuid == NULL) errx (1, "ropa_init: failed to create hashtable for clients_uuid"); ht_ccpairs = hashtabnew (hashsz_cc, ccpairs_cmp, ccpairs_hash); if (ht_ccpairs == NULL) errx (1, "ropa_init: failed to create hashtable for ccpairs"); lru_clients = listnew (); if (lru_clients == NULL) errx (1, "ropa_init: failed to create lru for clients"); lru_ccpair = listnew (); if (lru_ccpair == NULL) errx (1, "ropa_init: failed to create list for ccpairs"); lru_callback = listnew (); if (lru_callback == NULL) errx (1, "ropa_init: failed to create list for callback"); heap_ccpairs = heap_new (num_cc, ccpair_cmp_time); if (heap_ccpairs == NULL) errx (1, "ropa_init: failed to create heap for ccpairs"); create_clients(num_cli); create_callbacks(num_cb); create_ccpairs(num_cc); uuid_init_simple (&server_uuid, 0x82ED305E); if (LWP_CreateProcess (heapcleaner, ROPA_STACKSIZE, 1, NULL, "heap-invalidator", &cleaner_pid)) errx (1, "ropa_init: LWP_CreateProcess failed"); debuglevel = mlog_log_get_level_num(); /* XXX */ return 0; }
void rxi_StartServerProc(void *(*proc) (void *), int stacksize) { PROCESS scratchPid; static int number = 0; char name[32]; sprintf(name, "srv_%d", ++number); LWP_CreateProcess(proc, stacksize, RX_PROCESS_PRIORITY, NULL, "rx_ServerProc", &scratchPid); if (registerProgram) (*registerProgram) (scratchPid, name); }
static void arla_start (char *device_file, const char *cache_dir) { struct kernel_args kernel_args; PROCESS kernelpid; signal (SIGINT, sigint); signal (SIGTERM, sigint); signal (SIGHUP, sighup); umask (S_IRWXG|S_IRWXO); /* 077 */ #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE) prctl(PR_SET_DUMPABLE, 1); #endif nnpfs_message_init (); kernel_opendevice (device_file); kernel_args.num_workers = num_workers; if (LWP_CreateProcess (kernel_interface, KERNEL_STACKSIZE, 1, (char *)&kernel_args, "Kernel-interface", &kernelpid)) arla_errx (1, ADEBERROR, "Cannot create kernel-interface process"); write_pid_file ("arlad"); if (chroot (cache_dir) < 0) arla_err (1, ADEBERROR, errno, "chroot %s", cache_dir); if (chdir("/") < 0) arla_err (1, ADEBERROR, errno, "chdir /"); if (fork_flag) kill(getppid(), SIGUSR1); if (pw) { if (setgroups(1, &pw->pw_gid) == -1 || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) arla_err (1, ADEBERROR, errno, "revoke"); } LWP_WaitProcess ((char *)arla_start); abort (); }
void _ko_resolve_init(void) { char *errmem; int ret; IOMGR_Initialize(); if (LWP_CreateProcess(ares_worker_thread, AFS_LWP_MINSTACKSIZE, 0, 0, "ares resolver daemon", &ares_pid)) errx(1, "Couldn't initialize resolver, helper thread didn't start"); /* XXX use ARES_FLAG_NOSEARCH */ ret = ares_init(&achannel); if (ret != ARES_SUCCESS) errx(1, "Couldn't initialize resolver: %s", ares_strerror(ret, &errmem)); }
int main(int argc, char **argv) { struct timeval t1, t2; PROCESS pid, otherpid; long i, count, x; static char c[] = "OtherProcess"; count = argc > 1 ? atoi(argv[1]) : 10000; cont_sw_threshold.tv_sec = 0; cont_sw_threshold.tv_usec = 10000; last_context_switch.tv_sec = 0; last_context_switch.tv_usec = 0; assert(LWP_Init(LWP_VERSION, 0, &pid) == LWP_SUCCESS); assert(LWP_CreateProcess(OtherProcess, 16384, 0, (char *)pid, c, &otherpid) == LWP_SUCCESS); assert(IOMGR_Initialize() == LWP_SUCCESS); gettimeofday(&t1, NULL); for (i = 0; i < count; i++) { #if 0 LWP_DispatchProcess(); #else LWP_QSignal(otherpid); LWP_QWait(); #endif } gettimeofday(&t2, NULL); if (count) { x = (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec); printf("%ld milliseconds for %ld Yields (%f usec per Yield)\n", x / 1000, count, (float)(x / count)); } LWP_TerminateProcessSupport(); exit(EXIT_SUCCESS); }
void conn_init (unsigned nentries) { arla_warnx (ADEBCONN, "initconncache"); connhtab = hashtabnew (CONNCACHESIZE, conncmp, connhash); if (connhtab == NULL) arla_errx (1, ADEBERROR, "conn_init: hashtabnew failed"); connfreelist = listnew (); if (connfreelist == NULL) arla_errx (1, ADEBERROR, "conn_init: listnew failed"); connprobelist = listnew (); if (connprobelist == NULL) arla_errx (1, ADEBERROR, "conn_init: listnew failed"); nconnections = 0; if (LWP_CreateProcess (pinger, PINGER_STACKSIZE, 1, NULL, "pinger", &pinger_pid)) arla_errx (1, ADEBERROR, "conn: cannot create pinger thread"); create_new_connections (nentries); }
main(int ac, char **av) { int i; int on = 1; short port = -1; /* host order. */ int setFD = 0; struct sockaddr_in saddr; int acceptFD; clientHandle_t *clientHandle; int code; int addr_len; PROCESS pid; fd_set *rfds, *wfds, *efds; int sockFD; program = av[0]; if (ac < 2) Usage(); /* lwp_debug = 1; */ signal(SIGIO, sigIO); for (i = 1; i < ac; i++) { if (!strcmp("-fd", av[i])) { if (++i >= ac) { printf("Missing number for -fd option.\n"); Usage(); } setFD = atoi(av[i]); if (setFD <= 2) { printf("%d: file descriptor must be at least 3.\n", setFD); Usage(); } } else { if (port == -1) { port = atoi(av[i]); if (port <= 0) { printf("%s: port must be at least 1\n", av[i]); Usage(); } } else { printf("%s: Unknown argument.\n", av[i]); } } } if (port == -1) { printf("Missing port.\n"); Usage(); } if (!setFD) { setFD = 31; printf("Using default socket of %d.\n", setFD); } OpenFDs(setFD); IOMGR_Initialize(); /* Setup server processes */ for (i = 0; i < MAX_THREADS; i++) { if (LWP_CreateProcess (handleRequest, 32768, LWP_NORMAL_PRIORITY, (char *)&clientHandles[i], "HandleRequestThread", &pid) < 0) { printf("%s: Failed to start all LWP's\n", program); exit(1); } clientHandles[i].ch_pid = pid; } sockFD = socket(AF_INET, SOCK_STREAM, 0); if (sockFD < 0) { perror("socket"); exit(1); } Log("Using socket at file descriptor %d.\n", sockFD); if (setsockopt(sockFD, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { perror("setsockopt: "); exit(1); } memset((void *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = ntohs(port); saddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sockFD, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind: "); exit(1); } rfds = IOMGR_AllocFDSet(); wfds = IOMGR_AllocFDSet(); efds = IOMGR_AllocFDSet(); if (!rfds || !wfds || !efds) { printf("main: Could not alloc fd_set's.\n"); exit(1); } listen(sockFD, 100); while (1) { FD_ZERO(rfds); FD_ZERO(wfds); FD_ZERO(efds); FD_SET(sockFD, rfds); FD_SET(sockFD, efds); Log("Main - going to select.\n"); code = IOMGR_Select(sockFD + 1, rfds, wfds, efds, (struct timeval *)0); switch (code) { case 0: /* Timer, can't happen here. */ case -1: case -2: Log("Oops! select returns %d!\n", code); abort(); default: if (FD_ISSET(sockFD, efds)) { recvOOB(sockFD); assertNullFDSet(sockFD, rfds); assertNullFDSet(-1, wfds); assertNullFDSet(sockFD, efds); } if (FD_ISSET(sockFD, rfds)) { while (nThreads > MAX_THREADS) { IOMGR_Sleep(1); } clientHandle = getClientHandle(); addr_len = sizeof(clientHandle->ch_addr); clientHandle->ch_fd = accept(sockFD, (struct sockaddr *) &clientHandle->ch_addr, &addr_len); if (clientHandle->ch_fd < 0) { perror("accept: "); exit(1); } Log("Main - signalling LWP 0x%x\n", &clientHandle->ch_state); LWP_NoYieldSignal(&clientHandle->ch_state); assertNullFDSet(sockFD, rfds); assertNullFDSet(-1, wfds); assertNullFDSet(-1, efds); break; } Die(1, "(main) No data to read.\n"); } } }
int fsprobe_Init(int a_numServers, struct sockaddr_in *a_socketArray, int a_ProbeFreqInSecs, int (*a_ProbeHandler)(void), int a_debug) { /*fsprobe_Init */ static char rn[] = "fsprobe_Init"; /*Routine name */ register afs_int32 code; /*Return value */ static struct rx_securityClass *CBsecobj; /*Callback security object */ struct rx_securityClass *secobj; /*Client security object */ struct rx_service *rxsrv_afsserver; /*Server for AFS */ int arg_errfound; /*Argument error found? */ int curr_srv; /*Current server idx */ struct fsprobe_ConnectionInfo *curr_conn; /*Ptr to current conn */ char *hostNameFound; /*Ptr to returned host name */ int conn_err; /*Connection error? */ int PortToUse; /*Callback port to use */ /* * If we've already been called, snicker at the bozo, gently * remind him of his doubtful heritage, and return success. */ if (fsprobe_initflag) { fprintf(stderr, "[%s] Called multiple times!\n", rn); return (0); } else fsprobe_initflag = 1; /* * Check the parameters for bogosities. */ arg_errfound = 0; if (a_numServers <= 0) { fprintf(stderr, "[%s] Illegal number of servers: %d\n", rn, a_numServers); arg_errfound = 1; } if (a_socketArray == (struct sockaddr_in *)0) { fprintf(stderr, "[%s] Null server socket array argument\n", rn); arg_errfound = 1; } if (a_ProbeFreqInSecs <= 0) { fprintf(stderr, "[%s] Illegal probe frequency: %d\n", rn, a_ProbeFreqInSecs); arg_errfound = 1; } if (a_ProbeHandler == (int (*)())0) { fprintf(stderr, "[%s] Null probe handler function argument\n", rn); arg_errfound = 1; } if (arg_errfound) return (-1); /* * Record our passed-in info. */ fsprobe_debug = a_debug; fsprobe_numServers = a_numServers; fsprobe_Handler = a_ProbeHandler; fsprobe_ProbeFreqInSecs = a_ProbeFreqInSecs; /* * Get ready in case we have to do a cleanup - basically, zero * everything out. */ fsprobe_CleanupInit(); /* * Allocate the necessary data structures and initialize everything * else. */ fsprobe_ConnInfo = (struct fsprobe_ConnectionInfo *) malloc(a_numServers * sizeof(struct fsprobe_ConnectionInfo)); if (fsprobe_ConnInfo == (struct fsprobe_ConnectionInfo *)0) { fprintf(stderr, "[%s] Can't allocate %d connection info structs (%"AFS_SIZET_FMT" bytes)\n", rn, a_numServers, (a_numServers * sizeof(struct fsprobe_ConnectionInfo))); return (-1); /*No cleanup needs to be done yet */ } #if 0 else fprintf(stderr, "[%s] fsprobe_ConnInfo allocated (%d bytes)\n", rn, a_numServers * sizeof(struct fsprobe_ConnectionInfo)); #endif /* 0 */ fsprobe_statsBytes = a_numServers * sizeof(struct ProbeViceStatistics); fsprobe_Results.stats = (struct ProbeViceStatistics *) malloc(fsprobe_statsBytes); if (fsprobe_Results.stats == NULL) { fprintf(stderr, "[%s] Can't allocate %d statistics structs (%d bytes)\n", rn, a_numServers, fsprobe_statsBytes); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (-1); } else if (fsprobe_debug) fprintf(stderr, "[%s] fsprobe_Results.stats allocated (%d bytes)\n", rn, fsprobe_statsBytes); fsprobe_probeOKBytes = a_numServers * sizeof(int); fsprobe_Results.probeOK = (int *)malloc(fsprobe_probeOKBytes); if (fsprobe_Results.probeOK == (int *)0) { fprintf(stderr, "[%s] Can't allocate %d probeOK array entries (%d bytes)\n", rn, a_numServers, fsprobe_probeOKBytes); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (-1); } else if (fsprobe_debug) fprintf(stderr, "[%s] fsprobe_Results.probeOK allocated (%d bytes)\n", rn, fsprobe_probeOKBytes); fsprobe_Results.probeNum = 0; fsprobe_Results.probeTime = 0; memset(fsprobe_Results.stats, 0, (a_numServers * sizeof(struct ProbeViceStatistics))); /* * Initialize the Rx subsystem, just in case nobody's done it. */ if (fsprobe_debug) fprintf(stderr, "[%s] Initializing Rx\n", rn); PortToUse = FSPROBE_CBPORT; do { code = rx_Init(htons(PortToUse)); if (code) { if (code == RX_ADDRINUSE) { if (fsprobe_debug) fprintf(stderr, "[%s] Callback port %d in use, advancing\n", rn, PortToUse); PortToUse++; } else { fprintf(stderr, "[%s] Fatal error in rx_Init()\n", rn); return (-1); } } } while (code); if (fsprobe_debug) fprintf(stderr, "[%s] Rx initialized on port %d\n", rn, PortToUse); /* * Create a null Rx server security object, to be used by the * Callback listener. */ CBsecobj = rxnull_NewServerSecurityObject(); if (CBsecobj == (struct rx_securityClass *)0) { fprintf(stderr, "[%s] Can't create null security object for the callback listener.\n", rn); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (-1); } if (fsprobe_debug) fprintf(stderr, "[%s] Callback server security object created\n", rn); /* * Create a null Rx client security object, to be used by the * probe LWP. */ secobj = rxnull_NewClientSecurityObject(); if (secobj == (struct rx_securityClass *)0) { fprintf(stderr, "[%s] Can't create client security object for probe LWP.\n", rn); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (-1); } if (fsprobe_debug) fprintf(stderr, "[%s] Probe LWP client security object created\n", rn); curr_conn = fsprobe_ConnInfo; conn_err = 0; for (curr_srv = 0; curr_srv < a_numServers; curr_srv++) { /* * Copy in the socket info for the current server, resolve its * printable name if possible. */ if (fsprobe_debug) { fprintf(stderr, "[%s] Copying in the following socket info:\n", rn); fprintf(stderr, "[%s] IP addr 0x%x, port %d\n", rn, (a_socketArray + curr_srv)->sin_addr.s_addr, (a_socketArray + curr_srv)->sin_port); } memcpy(&(curr_conn->skt), a_socketArray + curr_srv, sizeof(struct sockaddr_in)); hostNameFound = hostutil_GetNameByINet(curr_conn->skt.sin_addr.s_addr); if (hostNameFound == NULL) { fprintf(stderr, "[%s] Can't map Internet address %u to a string name\n", rn, curr_conn->skt.sin_addr.s_addr); curr_conn->hostName[0] = '\0'; } else { strcpy(curr_conn->hostName, hostNameFound); if (fsprobe_debug) fprintf(stderr, "[%s] Host name for server index %d is %s\n", rn, curr_srv, curr_conn->hostName); } /* * Make an Rx connection to the current server. */ if (fsprobe_debug) fprintf(stderr, "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n", rn, curr_srv, curr_conn->skt.sin_addr.s_addr, curr_conn->skt.sin_port); curr_conn->rxconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr, /*Server addr */ curr_conn->skt.sin_port, /*Server port */ 1, /*AFS service num */ secobj, /*Security object */ 0); /*Number of above */ if (curr_conn->rxconn == (struct rx_connection *)0) { fprintf(stderr, "[%s] Can't create Rx connection to server %s (%u)\n", rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr); conn_err = 1; } if (fsprobe_debug) fprintf(stderr, "[%s] New connection at %p\n", rn, curr_conn->rxconn); /* * Make an Rx connection to the current volume server. */ if (fsprobe_debug) fprintf(stderr, "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n", rn, curr_srv, curr_conn->skt.sin_addr.s_addr, htons(7005)); curr_conn->rxVolconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr, /*Server addr */ htons(AFSCONF_VOLUMEPORT), /*Volume Server port */ VOLSERVICE_ID, /*AFS service num */ secobj, /*Security object */ 0); /*Number of above */ if (curr_conn->rxVolconn == (struct rx_connection *)0) { fprintf(stderr, "[%s] Can't create Rx connection to volume server %s (%u)\n", rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr); conn_err = 1; } else { int i, cnt; memset(&curr_conn->partList, 0, sizeof(struct partList)); curr_conn->partCnt = 0; i = XListPartitions(curr_conn->rxVolconn, &curr_conn->partList, &cnt); if (!i) { curr_conn->partCnt = cnt; } } if (fsprobe_debug) fprintf(stderr, "[%s] New connection at %p\n", rn, curr_conn->rxVolconn); /* * Bump the current fsprobe connection to set up. */ curr_conn++; } /*for curr_srv */ /* * Create the AFS callback service (listener). */ if (fsprobe_debug) fprintf(stderr, "[%s] Creating AFS callback listener\n", rn); rxsrv_afsserver = rx_NewService(0, /*Use default port */ 1, /*Service ID */ "afs", /*Service name */ &CBsecobj, /*Ptr to security object(s) */ 1, /*Number of security objects */ RXAFSCB_ExecuteRequest); /*Dispatcher */ if (rxsrv_afsserver == (struct rx_service *)0) { fprintf(stderr, "[%s] Can't create callback Rx service/listener\n", rn); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (-1); } if (fsprobe_debug) fprintf(stderr, "[%s] Callback listener created\n", rn); /* * Start up the AFS callback service. */ if (fsprobe_debug) fprintf(stderr, "[%s] Starting up callback listener.\n", rn); rx_StartServer(0 /*Don't donate yourself to LWP pool */ ); /* * Start up the probe LWP. */ if (fsprobe_debug) fprintf(stderr, "[%s] Creating the probe LWP\n", rn); code = LWP_CreateProcess(fsprobe_LWP, /*Function to start up */ LWP_STACK_SIZE, /*Stack size in bytes */ 1, /*Priority */ (void *)0, /*Parameters */ "fsprobe Worker", /*Name to use */ &probeLWP_ID); /*Returned LWP process ID */ if (code) { fprintf(stderr, "[%s] Can't create fsprobe LWP! Error is %d\n", rn, code); fsprobe_Cleanup(1); /*Delete already-malloc'ed areas */ return (code); } if (fsprobe_debug) fprintf(stderr, "[%s] Probe LWP process structure located at %p\n", rn, probeLWP_ID); #if 0 /* * Do I need to do this? */ if (fsprobe_debug) fprintf(stderr, "[%s] Calling osi_Wakeup()\n", rn); osi_Wakeup(&rxsrv_afsserver); /*Wake up anyone waiting for it */ #endif /* 0 */ /* * Return the final results. */ if (conn_err) return (-2); else return (0); } /*fsprobe_Init */
/* 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); }
int main(int argc, char **argv) { afs_int32 code; struct rx_securityClass **securityClasses; afs_int32 numClasses; struct rx_service *service; struct ktc_encryptionKey tkey; int rxpackets = 100; int rxJumbograms = 0; /* default is to send and receive jumbograms. */ int rxMaxMTU = -1; int bufSize = 0; /* temp variable to read in udp socket buf size */ afs_uint32 host = ntohl(INADDR_ANY); char *auditFileName = NULL; VolumePackageOptions opts; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGABRT, &nsa, NULL); sigaction(SIGSEGV, &nsa, NULL); #endif osi_audit_init(); osi_audit(VS_StartEvent, 0, AUD_END); /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } TTsleep = TTrun = 0; /* parse cmd line */ for (code = 1; code < argc; code++) { if (strcmp(argv[code], "-log") == 0) { /* set extra logging flag */ DoLogging = 1; } else if (strcmp(argv[code], "-help") == 0) { goto usage; } else if (strcmp(argv[code], "-rxbind") == 0) { rxBind = 1; } else if (strcmp(argv[code], "-allow-dotted-principals") == 0) { rxkadDisableDotCheck = 1; } else if (strcmp(argv[code], "-d") == 0) { if ((code + 1) >= argc) { fprintf(stderr, "missing argument for -d\n"); return -1; } debuglevel = atoi(argv[++code]); LogLevel = debuglevel; } else if (strcmp(argv[code], "-p") == 0) { lwps = atoi(argv[++code]); if (lwps > MAXLWP) { printf("Warning: '-p %d' is too big; using %d instead\n", lwps, MAXLWP); lwps = MAXLWP; } } else if (strcmp(argv[code], "-auditlog") == 0) { auditFileName = argv[++code]; } else if (strcmp(argv[code], "-audit-interface") == 0) { char *interface = argv[++code]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); return -1; } } else if (strcmp(argv[code], "-nojumbo") == 0) { rxJumbograms = 0; } else if (strcmp(argv[code], "-jumbo") == 0) { rxJumbograms = 1; } else if (!strcmp(argv[code], "-rxmaxmtu")) { if ((code + 1) >= argc) { fprintf(stderr, "missing argument for -rxmaxmtu\n"); exit(1); } rxMaxMTU = atoi(argv[++code]); if ((rxMaxMTU < RX_MIN_PACKET_SIZE) || (rxMaxMTU > RX_MAX_PACKET_DATA_SIZE)) { printf("rxMaxMTU %d invalid; must be between %d-%" AFS_SIZET_FMT "\n", rxMaxMTU, RX_MIN_PACKET_SIZE, RX_MAX_PACKET_DATA_SIZE); exit(1); } } else if (strcmp(argv[code], "-sleep") == 0) { sscanf(argv[++code], "%d/%d", &TTsleep, &TTrun); if ((TTsleep < 0) || (TTrun <= 0)) { printf("Warning: '-sleep %d/%d' is incorrect; ignoring\n", TTsleep, TTrun); TTsleep = TTrun = 0; } } else if (strcmp(argv[code], "-mbpersleep") == 0) { sscanf(argv[++code], "%d", &MBperSecSleep); if (MBperSecSleep < 0) MBperSecSleep = 0; } else if (strcmp(argv[code], "-udpsize") == 0) { if ((code + 1) >= argc) { printf("You have to specify -udpsize <integer value>\n"); exit(1); } sscanf(argv[++code], "%d", &bufSize); if (bufSize < rx_GetMinUdpBufSize()) printf ("Warning:udpsize %d is less than minimum %d; ignoring\n", bufSize, rx_GetMinUdpBufSize()); else udpBufSize = bufSize; } else if (strcmp(argv[code], "-enable_peer_stats") == 0) { rx_enablePeerRPCStats(); } else if (strcmp(argv[code], "-enable_process_stats") == 0) { rx_enableProcessRPCStats(); } else if (strcmp(argv[code], "-preserve-vol-stats") == 0) { DoPreserveVolumeStats = 1; } else if (strcmp(argv[code], "-sync") == 0) { if ((code + 1) >= argc) { printf("You have to specify -sync <sync_behavior>\n"); exit(1); } ih_PkgDefaults(); if (ih_SetSyncBehavior(argv[++code])) { printf("Invalid -sync value %s\n", argv[code]); exit(1); } } #ifndef AFS_NT40_ENV else if (strcmp(argv[code], "-syslog") == 0) { /* set syslog logging flag */ serverLogSyslog = 1; } else if (strncmp(argv[code], "-syslog=", 8) == 0) { serverLogSyslog = 1; serverLogSyslogFacility = atoi(argv[code] + 8); } #endif #ifdef AFS_PTHREAD_ENV else if (strcmp(argv[code], "-convert") == 0) convertToOsd = 1; else if (strcmp(argv[code], "-libafsosd") == 0) libafsosd = 1; #endif else { printf("volserver: unrecognized flag '%s'\n", argv[code]); usage: #ifndef AFS_NT40_ENV printf("Usage: volserver [-log] [-p <number of processes>] " "[-auditlog <log path>] [-d <debug level>] " "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-udpsize <size of socket buffer in bytes>] " "[-syslog[=FACILITY]] -mbpersleep <MB / 1 sec sleep>" "%s" "[-enable_peer_stats] [-enable_process_stats] " "[-sync <always | delayed | onclose | never>] " #ifdef AFS_PTHREAD_ENV , libafsosd ? "[-convert] ":"", #endif "[-help]\n"); #else printf("Usage: volserver [-log] [-p <number of processes>] " "[-auditlog <log path>] [-d <debug level>] " "[-nojumbo] [-jumbo] [-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-udpsize <size of socket buffer in bytes>] " "[-enable_peer_stats] [-enable_process_stats] " "[-sync <always | delayed | onclose | never>] " "[-help]\n"); #endif VS_EXIT(1); } } if (auditFileName) { osi_audit_file(auditFileName); osi_audit(VS_StartEvent, 0, AUD_END); } #ifdef AFS_SGI_VNODE_GLUE if (afs_init_kernel_config(-1) < 0) { printf ("Can't determine NUMA configuration, not starting volserver.\n"); exit(1); } #endif InitErrTabs(); #ifdef AFS_PTHREAD_ENV SetLogThreadNumProgram( threadNum ); #endif #ifdef AFS_NT40_ENV if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); printf("Volume server unable to start winsock, exiting.\n"); exit(1); } #endif /* Open VolserLog and map stdout, stderr into it; VInitVolumePackage2 can log, so we need to do this here */ OpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATH); VOptDefaults(volumeServer, &opts); #ifdef AFS_PTHREAD_ENV if (libafsosd) { extern struct vol_data_v0 vol_data_v0; extern struct volser_data_v0 volser_data_v0; struct init_volser_inputs input = { &vol_data_v0, &volser_data_v0 }; struct init_volser_outputs output = { &osdvol, &osdvolser }; code = load_libafsosd("init_volser_afsosd", &input, &output); if (code) { ViceLog(0, ("Loading libafsosd.so failed with code %d, aborting\n", code)); return -1; } } #endif if (VInitVolumePackage2(volumeServer, &opts)) { Log("Shutting down: errors encountered initializing volume package\n"); exit(1); } /* For nuke() */ Lock_Init(&localLock); DInit(40); #ifndef AFS_PTHREAD_ENV vol_PollProc = IOMGR_Poll; /* tell vol pkg to poll io system periodically */ #endif #ifndef AFS_NT40_ENV rxi_syscallp = volser_syscall; #endif rx_nPackets = rxpackets; /* set the max number of packets */ if (udpBufSize) rx_SetUdpBufSize(udpBufSize); /* set the UDP buffer size for receive */ 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, (int)htons(AFSCONF_VOLUMEPORT)); if (code) { fprintf(stderr, "rx init failed on socket AFSCONF_VOLUMEPORT %u\n", AFSCONF_VOLUMEPORT); VS_EXIT(1); } if (!rxJumbograms) { /* Don't allow 3.4 vos clients to send jumbograms and we don't send. */ rx_SetNoJumbo(); } if (rxMaxMTU != -1) { rx_SetMaxMTU(rxMaxMTU); } rx_GetIFInfo(); #ifndef AFS_PTHREAD_ENV rx_SetRxDeadTime(420); #endif memset(busyFlags, 0, sizeof(busyFlags)); SetupLogSignals(); { #ifdef AFS_PTHREAD_ENV pthread_t tid; pthread_attr_t tattr; osi_Assert(pthread_attr_init(&tattr) == 0); osi_Assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0); osi_Assert(pthread_create(&tid, &tattr, BKGLoop, NULL) == 0); #else PROCESS pid; LWP_CreateProcess(BKGLoop, 16*1024, 3, 0, "vol bkg daemon", &pid); LWP_CreateProcess(BKGSleep,16*1024, 3, 0, "vol slp daemon", &pid); #endif } /* 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 */ tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { Abort("volser: could not open conf files in %s\n", AFSDIR_SERVER_ETC_DIRPATH); VS_EXIT(1); } afsconf_GetKey(tdir, 999, &tkey); afsconf_BuildServerSecurityObjects(tdir, 0, &securityClasses, &numClasses); if (securityClasses[0] == NULL) Abort("rxnull_NewServerSecurityObject"); service = rx_NewServiceHost(host, 0, VOLSERVICE_ID, "VOLSER", securityClasses, numClasses, AFSVolExecuteRequest); if (service == (struct rx_service *)0) Abort("rx_NewService"); rx_SetBeforeProc(service, MyBeforeProc); rx_SetAfterProc(service, MyAfterProc); rx_SetIdleDeadTime(service, 0); /* never timeout */ if (lwps < 4) lwps = 4; rx_SetMaxProcs(service, lwps); #if defined(AFS_XBSD_ENV) rx_SetStackSize(service, (128 * 1024)); #elif defined(AFS_SGI_ENV) rx_SetStackSize(service, (48 * 1024)); #else rx_SetStackSize(service, (32 * 1024)); #endif if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(service, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } service = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); if (service == (struct rx_service *)0) Abort("rx_NewService"); rx_SetMinProcs(service, 2); rx_SetMaxProcs(service, 4); #ifdef AFS_PTHREAD_ENV if (libafsosd) { service = rx_NewService(0, 7, "afsosd", securityClasses, numClasses, (osdvolser->op_AFSVOLOSD_ExecuteRequest)); if (!service) { ViceLog(0, ("Failed to initialize afsosd rpc service.\n")); exit(-1); } rx_SetBeforeProc(service, MyBeforeProc); rx_SetAfterProc(service, MyAfterProc); rx_SetIdleDeadTime(service, 0); /* never timeout */ rx_SetMinProcs(service, 2); if (lwps < 4) lwps = 4; rx_SetMaxProcs(service, lwps); #if defined(AFS_XBSD_ENV) rx_SetStackSize(service, (128 * 1024)); #elif defined(AFS_SGI_ENV) rx_SetStackSize(service, (48 * 1024)); #else rx_SetStackSize(service, (32 * 1024)); #endif } #endif /* AFS_PTHREAD_ENV */ LogCommandLine(argc, argv, "Volserver", VolserVersion, "Starting AFS", Log); FT_GetTimeOfDay(&statisticStart, 0); if (afsconf_GetLatestKey(tdir, NULL, NULL) == 0) { LogDesWarning(); } if (TTsleep) { Log("Will sleep %d second%s every %d second%s\n", TTsleep, (TTsleep > 1) ? "s" : "", TTrun + TTsleep, (TTrun + TTsleep > 1) ? "s" : ""); } /* allow super users to manage RX statistics */ /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(vol_rxstat_userok); rx_StartServer(1); /* Donate this process to the server process pool */ osi_audit(VS_FinishEvent, (-1), AUD_END); Abort("StartServer returned?"); return 0; /* not reached */ }
afs_int32 init_krb_udp(void) #endif { struct sockaddr_in taddr; static PROCESS slPid; /* socket listener pid */ static PROCESS checkPid; /* fiveminute check */ afs_int32 code; char *krb4name; /* kerberos version4 service */ #if MAIN PROCESS junk; #endif struct servent *sp; static int inited = 0; afs_int32 kerb_port; if (inited) return -1; inited = 1; memset(&taddr, 0, sizeof(taddr)); krb4name = "kerberos4"; sp = getservbyname(krb4name, "udp"); taddr.sin_family = AF_INET; /* added for NCR port */ #ifdef STRUCT_SOCKADDR_HAS_SA_LEN taddr.sin_len = sizeof(struct sockaddr_in); #endif if (!sp) { /* if kerberos-4 is not available, try "kerberos-iv" */ krb4name = "kerberos-iv"; sp = getservbyname(krb4name, "udp"); } if (!sp) { /* if kerberos-iv is not available, try "kerberos" */ krb4name = "kerberos"; sp = getservbyname(krb4name, "udp"); } if (!sp) { fprintf(stderr, "kerberos/udp is unknown; check /etc/services. Using port=%d as default\n", KRB_PORT); taddr.sin_port = htons(KRB_PORT); } else { /* copy the port number */ fprintf(stderr, "%s/udp port=%hu\n", krb4name, (unsigned short)sp->s_port); taddr.sin_port = sp->s_port; } kerb_port = taddr.sin_port; sock_kerb = socket(AF_INET, SOCK_DGRAM, 0); code = bind(sock_kerb, (struct sockaddr *)&taddr, sizeof(taddr)); if (code < 0) { perror("calling bind"); sock_kerb = -1; } sp = getservbyname("kerberos5", "udp"); if (!sp) { fprintf(stderr, "kerberos5/udp is unknown; check /etc/services. Using port=%d as default\n", KRB5_PORT); taddr.sin_port = htons(KRB5_PORT); } else { /* copy the port number */ fprintf(stderr, "kerberos5/udp port=%hu\n", (unsigned short)sp->s_port); taddr.sin_port = sp->s_port; } if (taddr.sin_port != kerb_port) { /* a different port */ sock_kerb5 = socket(AF_INET, SOCK_DGRAM, 0); code = bind(sock_kerb5, (struct sockaddr *)&taddr, sizeof(taddr)); if (code < 0) { perror("calling bind"); sock_kerb5 = -1; } } /* Bail out if we can't bind with any port */ if ((sock_kerb < 0) && (sock_kerb5 < 0)) return -1; #if MAIN /* this has already been done */ LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &junk); IOMGR_Initialize(); #endif LWP_CreateProcess(SocketListener, /*stacksize */ 16000, LWP_NORMAL_PRIORITY, (void *)0, "Socket Listener", &slPid); /* just to close the log every five minutes */ LWP_CreateProcess(FiveMinuteCheckLWP, 24 * 1024, LWP_MAX_PRIORITY - 2, (void *)&fiveminutes, "FiveMinuteChecks", &checkPid); #if MAIN initialize_ka_error_table(); initialize_rxk_error_table(); while (1) /* don't just stand there, run it */ IOMGR_Sleep(60); #else return 0; #endif }
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); }
static long RunHijackTest(struct clientParms *parms, long host, struct rx_securityClass *sc, long si) { #ifndef rx_GetPacketCksum code = RXKST_BADARGS; afs_com_err(whoami, code, "Older versions of Rx don't export packet tracing routines: can't run this HijackTest"); return code; #else long code; struct rx_connection *conn = 0; struct rx_connection *otherConn = 0; #ifdef AFS_PTHREAD_ENV pthread_t pid; #else PROCESS pid; #endif int nResp; /* otherConn responses seen */ long tmp_rc; #ifdef AFS_PTHREAD_ENV pthread_once(&slowCallOnce, SlowCallInit); #endif rx_justReceived = HandleIncoming; rx_almostSent = HandleOutgoing; incomingOps.op = IO_NOOP; outgoingOps.op = OO_NOOP; #define HIJACK_CONN(conn) \ { if (conn) rx_DestroyConnection (conn); \ (conn) = rx_NewConnection(host, htons(RXKST_SERVICEPORT), \ RXKST_SERVICEID, sc, si); \ if (!(conn)) return RXKST_NEWCONNFAILED; \ outgoingOps.client = 1; \ outgoingOps.epoch = (conn)->epoch; \ outgoingOps.cid = (conn)->cid; } HIJACK_CONN(conn); /* First try switching from no packet cksum to sending packet cksum between * calls, and see if server complains. */ outgoingOps.op = OO_ZEROCKSUM; code = FastCall(conn); if (code) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } /* The server thinks we're an old style client. Now start sending cksums. * Server shouldn't care. */ outgoingOps.op = OO_NOOP; code = FastCall(conn); if (code) { afs_com_err(whoami, code, "doing FastCall with non-ZEROCKSUM"); return code; } /* The server now thinks we're a new style client, we can't go back now. */ outgoingOps.op = OO_ZEROCKSUM; code = FastCall(conn); if (code == 0) code = RXKST_NOBADCKSUM; if (code != RXKADSEALEDINCON) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else if (!conn->error) { code = RXKST_NOCONNERROR; afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else code = 0; HIJACK_CONN(conn); /* Now try modifying packet cksum to see if server complains. */ outgoingOps.op = OO_MUNGCKSUM; code = FastCall(conn); if (code == 0) code = RXKST_NOBADCKSUM; if (code != RXKADSEALEDINCON) { afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else if (!conn->error) { code = RXKST_NOCONNERROR; afs_com_err(whoami, code, "doing FastCall with ZEROCKSUM"); return code; } else code = 0; /* Now make two connection and direct the first challenge on one connection * to the other connection to see if it generates a response. The * retransmitted challenge should allow the call on the first connection to * complete correctly. Part one is to attack a new connection, then attack * it after it has made a call. Part three, just for comparison, attacks a * otherConn while it is making a slow call (and thus has an active call). * Against this attack we have no defense so we expect a challenge in this * case, which the server will discard. */ #define RedirectChallenge(conn,otherConn) \ (incomingOps.epoch = (conn)->epoch, \ incomingOps.cid = (conn)->cid, \ incomingOps.client = 1, \ incomingOps.newEpoch = (otherConn)->epoch, \ incomingOps.newCid = (otherConn)->cid, \ incomingOps.op = IO_REDIRECTCHALLENGE, \ outgoingOps.epoch = (otherConn)->epoch, \ outgoingOps.cid = (otherConn)->cid, \ outgoingOps.client = 1, \ outgoingOps.op = OO_COUNT, \ outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] = 0) HIJACK_CONN(conn); HIJACK_CONN(otherConn) RedirectChallenge(conn, otherConn); code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > 0) { oracle: code = RXKST_CHALLENGEORACLE; afs_com_err(whoami, code, "misdirecting challenge"); return code; } code = FastCall(otherConn); /* generate some activity here */ if (code) return code; nResp = outgoingOps.counts[RX_PACKET_TYPE_RESPONSE]; assert(nResp >= 1); code = FastCall(conn); if (code) return code; if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] > nResp) goto oracle; HIJACK_CONN(conn); RedirectChallenge(conn, otherConn); /* otherConn was authenticated during part one */ code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 0) goto oracle; HIJACK_CONN(conn); RedirectChallenge(conn, otherConn); /* otherConn is still authenticated */ slowCallCode = RXKST_PROCESSCREATED; #ifdef AFS_PTHREAD_ENV { pthread_attr_t tattr; code = pthread_attr_init(&tattr); if (code) { afs_com_err(whoami, code, "can't pthread_attr_init slow call process"); return code; } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { afs_com_err(whoami, code, "can't pthread_attr_setdetachstate slow call process"); return code; } code = pthread_create(&pid, &tattr, SlowCall, (void *)otherConn); } #else code = LWP_CreateProcess(SlowCall, 16000, LWP_NORMAL_PRIORITY, (opaque) otherConn, "Slow Call Process", &pid); #endif if (code) { afs_com_err(whoami, code, "can't create slow call process"); return code; } #ifdef AFS_PTHREAD_ENV pthread_mutex_lock(&slowCallLock); while (slowCallCode == RXKST_PROCESSCREATED) pthread_cond_wait(&slowCallCV, &slowCallLock); #else while (slowCallCode == RXKST_PROCESSCREATED) LWP_WaitProcess(&slowCallCode); /* wait for process start */ #endif if (slowCallCode != RXKST_PROCESSRUNNING) { tmp_rc = slowCallCode; #ifdef AFS_PTHREAD_ENV pthread_mutex_unlock(&slowCallLock); #endif return tmp_rc; /* make sure didn't fail immediately */ } assert(incomingOps.op == IO_REDIRECTCHALLENGE); code = FastCall(conn); if (code) return code; assert(incomingOps.op == IO_COUNT); /* redirect code was triggered */ #ifdef AFS_PTHREAD_ENV while (slowCallCode == RXKST_PROCESSRUNNING) pthread_cond_wait(&slowCallCV, &slowCallLock); pthread_mutex_unlock(&slowCallLock); #else while (slowCallCode == RXKST_PROCESSRUNNING) LWP_WaitProcess(&slowCallCode); /* wait for process finish */ #endif if (outgoingOps.counts[RX_PACKET_TYPE_RESPONSE] != 1) goto oracle; rx_justReceived = 0; rx_almostSent = 0; rx_DestroyConnection(otherConn); rx_DestroyConnection(conn); return code; #endif /* rx_GetPacketCksum */ }
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); }
/* Initialize the file descriptor cache */ void ih_Initialize(void) { int i; osi_Assert(!ih_Inited); ih_Inited = 1; DLL_INIT_LIST(ihAvailHead, ihAvailTail); DLL_INIT_LIST(fdAvailHead, fdAvailTail); DLL_INIT_LIST(fdLruHead, fdLruTail); for (i = 0; i < I_HANDLE_HASH_SIZE; i++) { DLL_INIT_LIST(ihashTable[i].ihash_head, ihashTable[i].ihash_tail); } #if defined(AFS_NT40_ENV) fdMaxCacheSize = vol_io_params.fd_max_cachesize; #elif defined(AFS_SUN5_ENV) || defined(AFS_NBSD_ENV) { struct rlimit rlim; osi_Assert(getrlimit(RLIMIT_NOFILE, &rlim) == 0); rlim.rlim_cur = rlim.rlim_max; osi_Assert(setrlimit(RLIMIT_NOFILE, &rlim) == 0); fdMaxCacheSize = rlim.rlim_cur - vol_io_params.fd_handle_setaside; #ifdef AFS_NBSD_ENV /* XXX this is to avoid using up all system fd netbsd is * somewhat broken and have set maximum fd for a root process * to the same as system fd that is avaible, so if the * fileserver uses all up process fds, all system fd will be * used up too ! * * Check for this better */ fdMaxCacheSize /= 4; #endif fdMaxCacheSize = min(fdMaxCacheSize, vol_io_params.fd_max_cachesize); osi_Assert(fdMaxCacheSize > 0); } #elif defined(AFS_HPUX_ENV) /* Avoid problems with "UFSOpen: igetinode failed" panics on HPUX 11.0 */ fdMaxCacheSize = 0; #else { long fdMax = max(sysconf(_SC_OPEN_MAX) - vol_io_params.fd_handle_setaside, 0); fdMaxCacheSize = (int)min(fdMax, vol_io_params.fd_max_cachesize); } #endif fdCacheSize = min(fdMaxCacheSize, vol_io_params.fd_initial_cachesize); { #ifdef AFS_PTHREAD_ENV pthread_t syncer; pthread_attr_t tattr; pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); pthread_create(&syncer, &tattr, ih_sync_thread, NULL); #else /* AFS_PTHREAD_ENV */ PROCESS syncer; LWP_CreateProcess(ih_sync_thread, 16*1024, LWP_MAX_PRIORITY - 2, NULL, "ih_syncer", &syncer); #endif /* AFS_PTHREAD_ENV */ } }
int main(int argc, char **argv, char **envp) { struct rx_service *tservice; afs_int32 code; struct afsconf_dir *tdir; int noAuth = 0; int i; char namebuf[AFSDIR_PATH_MAX]; int rxMaxMTU = -1; afs_uint32 host = htonl(INADDR_ANY); char *auditFileName = NULL; struct rx_securityClass **securityClasses; afs_int32 numClasses; int DoPeerRPCStats = 0; int DoProcessRPCStats = 0; #ifndef AFS_NT40_ENV int nofork = 0; struct stat sb; #endif #ifdef AFS_AIX32_ENV struct sigaction nsa; /* for some reason, this permits user-mode RX to run a lot faster. * we do it here in the bosserver, so we don't have to do it * individually in each server. */ tweak_config(); /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); sigaction(SIGABRT, &nsa, NULL); #endif osi_audit_init(); signal(SIGFPE, bozo_insecureme); #ifdef AFS_NT40_ENV /* Initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "%s: Couldn't initialize winsock.\n", argv[0]); exit(2); } #endif /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } /* some path inits */ bozo_fileName = AFSDIR_SERVER_BOZCONF_FILEPATH; DoCore = AFSDIR_SERVER_LOGS_DIRPATH; /* initialize the list of dirpaths that the bosserver has * an interest in monitoring */ initBosEntryStats(); #if defined(AFS_SGI_ENV) /* offer some protection if AFS isn't loaded */ if (syscall(AFS_SYSCALL, AFSOP_ENDLOG) < 0 && errno == ENOPKG) { printf("bosserver: AFS doesn't appear to be configured in O.S..\n"); exit(1); } #endif #ifndef AFS_NT40_ENV /* save args for restart */ bozo_argc = argc; bozo_argv = malloc((argc+1) * sizeof(char*)); if (!bozo_argv) { fprintf(stderr, "%s: Failed to allocate argument list.\n", argv[0]); exit(1); } bozo_argv[0] = (char*)AFSDIR_SERVER_BOSVR_FILEPATH; /* expected path */ bozo_argv[bozo_argc] = NULL; /* null terminate list */ #endif /* AFS_NT40_ENV */ /* parse cmd line */ for (code = 1; code < argc; code++) { #ifndef AFS_NT40_ENV bozo_argv[code] = argv[code]; #endif /* AFS_NT40_ENV */ if (strcmp(argv[code], "-noauth") == 0) { /* set noauth flag */ noAuth = 1; } else if (strcmp(argv[code], "-log") == 0) { /* set extra logging flag */ DoLogging = 1; } #ifndef AFS_NT40_ENV else if (strcmp(argv[code], "-syslog") == 0) { /* set syslog logging flag */ DoSyslog = 1; } else if (strncmp(argv[code], "-syslog=", 8) == 0) { DoSyslog = 1; DoSyslogFacility = atoi(argv[code] + 8); } else if (strncmp(argv[code], "-cores=", 7) == 0) { if (strcmp((argv[code]+7), "none") == 0) DoCore = 0; else DoCore = (argv[code]+7); } else if (strcmp(argv[code], "-nofork") == 0) { nofork = 1; } #endif else if (strcmp(argv[code], "-enable_peer_stats") == 0) { DoPeerRPCStats = 1; } else if (strcmp(argv[code], "-enable_process_stats") == 0) { DoProcessRPCStats = 1; } else if (strcmp(argv[code], "-restricted") == 0) { bozo_isrestricted = 1; } else if (strcmp(argv[code], "-rxbind") == 0) { rxBind = 1; } else if (strcmp(argv[code], "-allow-dotted-principals") == 0) { rxkadDisableDotCheck = 1; } else if (!strcmp(argv[code], "-rxmaxmtu")) { if ((code + 1) >= argc) { fprintf(stderr, "missing argument for -rxmaxmtu\n"); exit(1); } rxMaxMTU = atoi(argv[++code]); } else if (strcmp(argv[code], "-auditlog") == 0) { auditFileName = argv[++code]; } else if (strcmp(argv[code], "-audit-interface") == 0) { char *interface = argv[++code]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); exit(1); } } else if (strncmp(argv[code], "-pidfiles=", 10) == 0) { DoPidFiles = (argv[code]+10); } else if (strncmp(argv[code], "-pidfiles", 9) == 0) { DoPidFiles = AFSDIR_BOSCONFIG_DIR; } else { /* hack to support help flag */ #ifndef AFS_NT40_ENV printf("Usage: bosserver [-noauth] [-log] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-syslog[=FACILITY]] " "[-restricted] " "[-enable_peer_stats] [-enable_process_stats] " "[-cores=<none|path>] \n" "[-pidfiles[=path]] " "[-nofork] " "[-help]\n"); #else printf("Usage: bosserver [-noauth] [-log] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-restricted] " "[-enable_peer_stats] [-enable_process_stats] " "[-cores=<none|path>] \n" "[-pidfiles[=path]] " "[-help]\n"); #endif fflush(stdout); exit(0); } } if (auditFileName) { osi_audit_file(auditFileName); } #ifndef AFS_NT40_ENV if (geteuid() != 0) { printf("bosserver: must be run as root.\n"); exit(1); } #endif if ((!DoSyslog) #ifndef AFS_NT40_ENV && ((lstat(AFSDIR_BOZLOG_FILE, &sb) == 0) && !(S_ISFIFO(sb.st_mode))) #endif ) { strcpy(namebuf, AFSDIR_BOZLOG_FILE); strcat(namebuf, ".old"); rk_rename(AFSDIR_BOZLOG_FILE, namebuf); /* try rename first */ bozo_logFile = fopen(AFSDIR_BOZLOG_FILE, "a"); if (!bozo_logFile) { printf("bosserver: can't initialize log file (%s).\n", AFSDIR_SERVER_BOZLOG_FILEPATH); exit(1); } /* keep log closed normally, so can be removed */ fclose(bozo_logFile); } else { #ifndef AFS_NT40_ENV openlog("bosserver", LOG_PID, DoSyslogFacility); #endif } /* * go into the background and remove our controlling tty, close open * file desriptors */ #ifndef AFS_NT40_ENV if (!nofork) daemon(1, 0); #endif /* ! AFS_NT40_ENV */ /* create useful dirs */ CreateDirs(DoCore); /* Write current state of directory permissions to log file */ DirAccessOK(); /* chdir to AFS log directory */ if (DoCore) chdir(DoCore); else chdir(AFSDIR_SERVER_LOGS_DIRPATH); /* try to read the key from the config file */ tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { /* try to create local cell config file */ struct afsconf_cell tcell; strcpy(tcell.name, "localcell"); tcell.numServers = 1; code = gethostname(tcell.hostName[0], MAXHOSTCHARS); if (code) { bozo_Log("failed to get hostname, code %d\n", errno); exit(1); } if (tcell.hostName[0][0] == 0) { bozo_Log("host name not set, can't start\n"); bozo_Log("try the 'hostname' command\n"); exit(1); } memset(tcell.hostAddr, 0, sizeof(tcell.hostAddr)); /* not computed */ code = afsconf_SetCellInfo(NULL, AFSDIR_SERVER_ETC_DIRPATH, &tcell); if (code) { bozo_Log ("could not create cell database in '%s' (code %d), quitting\n", AFSDIR_SERVER_ETC_DIRPATH, code); exit(1); } tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { bozo_Log ("failed to open newly-created cell database, quitting\n"); exit(1); } } /* opened the cell databse */ bozo_confdir = tdir; code = bnode_Init(); if (code) { printf("bosserver: could not init bnode package, code %d\n", code); exit(1); } bnode_Register("fs", &fsbnode_ops, 3); bnode_Register("dafs", &dafsbnode_ops, 4); bnode_Register("simple", &ezbnode_ops, 1); bnode_Register("cron", &cronbnode_ops, 2); #if defined(RLIMIT_CORE) && defined(HAVE_GETRLIMIT) { struct rlimit rlp; getrlimit(RLIMIT_CORE, &rlp); if (!DoCore) rlp.rlim_cur = 0; else rlp.rlim_max = rlp.rlim_cur = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlp); getrlimit(RLIMIT_CORE, &rlp); bozo_Log("Core limits now %d %d\n",(int)rlp.rlim_cur,(int)rlp.rlim_max); } #endif /* Read init file, starting up programs. Also starts watcher threads. */ if ((code = ReadBozoFile(0))) { bozo_Log ("bosserver: Something is wrong (%d) with the bos configuration file %s; aborting\n", code, AFSDIR_SERVER_BOZCONF_FILEPATH); exit(code); } 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]; } for (i = 0; i < 10; i++) { if (rxBind) { code = rx_InitHost(host, htons(AFSCONF_NANNYPORT)); } else { code = rx_Init(htons(AFSCONF_NANNYPORT)); } if (code) { bozo_Log("can't initialize rx: code=%d\n", code); sleep(3); } else break; } if (i >= 10) { bozo_Log("Bos giving up, can't initialize rx\n"); exit(code); } /* Set some rx config */ if (DoPeerRPCStats) rx_enablePeerRPCStats(); if (DoProcessRPCStats) rx_enableProcessRPCStats(); /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { if (rx_SetMaxMTU(rxMaxMTU) != 0) { bozo_Log("bosserver: rxMaxMTU %d is invalid\n", rxMaxMTU); exit(1); } } code = LWP_CreateProcess(BozoDaemon, BOZO_LWP_STACKSIZE, /* priority */ 1, /* param */ NULL , "bozo-the-clown", &bozo_pid); if (code) { bozo_Log("Failed to create daemon thread\n"); exit(1); } /* initialize audit user check */ osi_audit_set_user_check(bozo_confdir, bozo_IsLocalRealmMatch); bozo_CreateRxBindFile(host); /* for local scripts */ /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(bozo_rxstat_userok); afsconf_SetNoAuthFlag(tdir, noAuth); afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses); if (DoPidFiles) { bozo_CreatePidFile("bosserver", NULL, getpid()); } tservice = rx_NewServiceHost(host, 0, /* service id */ 1, "bozo", securityClasses, numClasses, BOZO_ExecuteRequest); rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); rx_SetStackSize(tservice, BOZO_LWP_STACKSIZE); /* so gethostbyname works (in cell stuff) */ if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); rx_StartServer(1); /* donate this process */ return 0; }
afs_int32 DumpDB(struct rx_call *call, int firstcall, /* 1 - init. 0 - no init */ afs_int32 maxLength, charListT *charListPtr, afs_int32 *done) { #ifdef AFS_PTHREAD_ENV pthread_t dumperPid, watcherPid; pthread_attr_t dumperPid_tattr; pthread_attr_t watcherPid_tattr; #else PROCESS dumperPid, watcherPid; #endif int readSize; afs_int32 code = 0; if (callPermitted(call) == 0) ERROR(BUDB_NOTPERMITTED); ObtainWriteLock(&dumpSyncPtr->ds_lock); /* If asking for zero bytes, then this is a call to reset the timeToLive * timer. Reset it if there is a dump in progress. */ if (maxLength == 0) { charListPtr->charListT_val = NULL; charListPtr->charListT_len = 0; *done = ((dumpSyncPtr->statusFlags == 0) ? 1 : 0); /* reset the clock on dump timeout */ dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC; goto error_exit; } if (dumpSyncPtr->statusFlags == 0) { if (!firstcall) ERROR(BUDB_DUMPFAILED); LogDebug(5, "Setup dump\n"); /* no dump in progress - setup and retake lock */ memset(dumpSyncPtr, 0, sizeof(*dumpSyncPtr)); /* ObtainWriteLock(&dumpSyncPtr->ds_lock); */ /* mark dump in progress */ dumpSyncPtr->statusFlags = 1; code = pipe(dumpSyncPtr->pipeFid); if (code) ERROR(errno); #ifdef AFS_PTHREAD_ENV /* Initialize the condition variables and the mutexes we use * to signal and synchronize the reader and writer threads. */ assert(pthread_cond_init(&dumpSyncPtr->ds_readerStatus_cond, (const pthread_condattr_t *)0) == 0); assert(pthread_cond_init(&dumpSyncPtr->ds_writerStatus_cond, (const pthread_condattr_t *)0) == 0); assert(pthread_mutex_init(&dumpSyncPtr->ds_readerStatus_mutex, (const pthread_mutexattr_t *)0) == 0); assert(pthread_mutex_init(&dumpSyncPtr->ds_writerStatus_mutex, (const pthread_mutexattr_t *)0) == 0); /* Initialize the thread attributes and launch the thread */ assert(pthread_attr_init(&dumperPid_tattr) == 0); assert(pthread_attr_setdetachstate(&dumperPid_tattr, PTHREAD_CREATE_DETACHED) == 0); assert(pthread_create(&dumperPid, &dumperPid_tattr, (void *)setupDbDump, NULL) == 0); #else code = LWP_CreateProcess(setupDbDump, 16384, 1, (void *)(intptr_t)dumpSyncPtr->pipeFid[1], "Database Dumper", &dumperPid); if (code) goto error_exit; #endif dumpSyncPtr->dumperPid = dumperPid; dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC; #ifdef AFS_PTHREAD_ENV /* Initialize the thread attributes and launch the thread */ assert(pthread_attr_init(&watcherPid_tattr) == 0); assert(pthread_attr_setdetachstate(&watcherPid_tattr, PTHREAD_CREATE_DETACHED) == 0); assert(pthread_create(&watcherPid, &watcherPid_tattr, (void *)dumpWatcher, NULL) == 0); #else /* now create the watcher thread */ code = LWP_CreateProcess(dumpWatcher, 16384, 1, 0, "Database Dump Watchdog", &watcherPid); #endif } else if (firstcall) ERROR(BUDB_LOCKED); /* now read the database and feed it to the rpc connection */ /* wait for data */ while (dumpSyncPtr->ds_bytes == 0) { /* if no more data */ if ((dumpSyncPtr->ds_writerStatus == DS_DONE) || (dumpSyncPtr->ds_writerStatus == DS_DONE_ERROR)) { break; } if (dumpSyncPtr->ds_writerStatus == DS_WAITING) { LogDebug(6, "wakup writer\n"); dumpSyncPtr->ds_writerStatus = 0; #ifdef AFS_PTHREAD_ENV assert(pthread_cond_broadcast(&dumpSyncPtr->ds_writerStatus_cond) == 0); #else code = LWP_SignalProcess(&dumpSyncPtr->ds_writerStatus); if (code) LogError(code, "BUDB_DumpDB: signal delivery failed\n"); #endif } LogDebug(6, "wait for writer\n"); dumpSyncPtr->ds_readerStatus = DS_WAITING; ReleaseWriteLock(&dumpSyncPtr->ds_lock); #ifdef AFS_PTHREAD_ENV assert(pthread_mutex_lock(&dumpSyncPtr->ds_readerStatus_mutex) == 0); assert(pthread_cond_wait(&dumpSyncPtr->ds_readerStatus_cond, &dumpSyncPtr->ds_readerStatus_mutex) == 0); assert(pthread_mutex_unlock(&dumpSyncPtr->ds_readerStatus_mutex) == 0); #else LWP_WaitProcess(&dumpSyncPtr->ds_readerStatus); #endif ObtainWriteLock(&dumpSyncPtr->ds_lock); } charListPtr->charListT_val = (char *)malloc(maxLength); readSize = read(dumpSyncPtr->pipeFid[0], charListPtr->charListT_val, maxLength); /* reset the clock on dump timeout */ dumpSyncPtr->timeToLive = time(0) + DUMP_TTL_INC; LogDebug(4, "read of len %d returned %d\n", maxLength, readSize); charListPtr->charListT_len = readSize; if (readSize == 0) { /* last chunk */ *done = 1; close(dumpSyncPtr->pipeFid[0]); dumpSyncPtr->statusFlags = 0; } else *done = 0; dumpSyncPtr->ds_bytes -= readSize; if (dumpSyncPtr->ds_writerStatus == DS_WAITING) { dumpSyncPtr->ds_writerStatus = 0; #ifdef AFS_PTHREAD_ENV assert(pthread_cond_broadcast(&dumpSyncPtr->ds_writerStatus_cond) == 0); #else code = LWP_SignalProcess(&dumpSyncPtr->ds_writerStatus); if (code) LogError(code, "BUDB_DumpDB: signal delivery failed\n"); #endif } error_exit: if (!code && (dumpSyncPtr->ds_writerStatus == DS_DONE_ERROR)) code = -1; ReleaseWriteLock(&dumpSyncPtr->ds_lock); 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); }
static int backupInit(void) { afs_int32 code; static int initd = 0; /* ever called? */ PROCESS watcherPid; PROCESS pid; /* LWP process ID */ /* Initialization */ initialize_CMD_error_table(); /* don't run more than once */ if (initd) { afs_com_err(whoami, 0, "Backup already initialized."); return 0; } initd = 1; code = bc_InitConfig((char *)DefaultConfDir); if (code) { afs_com_err(whoami, code, "Can't initialize from config files in directory '%s'", DefaultConfDir); return (code); } /* * Set up Rx. */ code = LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid); if (code) { afs_com_err(whoami, code, "; Can't initialize LWP"); return (code); } code = rx_Init(htons(0)); if (code) { afs_com_err(whoami, code, "; Can't initialize Rx"); return (code); } rx_SetRxDeadTime(60); /* VLDB initialization */ code = vldbClientInit(0, localauth, tcell, &cstruct, &tokenExpires); if (code) return (code); /* Backup database initialization */ code = udbClientInit(0, localauth, tcell); if (code) return (code); /* setup status monitoring thread */ initStatus(); code = LWP_CreateProcess(statusWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "statusWatcher", &watcherPid); if (code) { afs_com_err(whoami, code, "; Can't create status monitor task"); return (code); } return (0); }
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); }
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 long CallSimultaneously(u_int threads, opaque rock, long (*proc)(int, opaque)) { long code; int i; #ifdef AFS_PTHREAD_ENV pthread_once(&workerOnce, WorkerInit); #endif workers = 0; for (i = 0; i < threads; i++) { struct worker *w; #ifdef AFS_PTHREAD_ENV pthread_t pid; #else PROCESS pid; #endif assert(i < MAX_CTHREADS); w = (struct worker *)osi_Alloc(sizeof(struct worker)); memset(w, 0, sizeof(*w)); w->next = workers; workers = w; w->index = i; w->exitCode = RXKST_PROCESSRUNNING; w->rock = rock; w->proc = proc; #ifdef AFS_PTHREAD_ENV { pthread_attr_t tattr; code = pthread_attr_init(&tattr); if (code) { afs_com_err(whoami, code, "can't pthread_attr_init worker process"); return code; } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { afs_com_err(whoami, code, "can't pthread_attr_setdetachstate worker process"); return code; } code = pthread_create(&pid, &tattr, DoWorker, (void *)w); } #else code = LWP_CreateProcess(DoWorker, 16000, LWP_NORMAL_PRIORITY, (opaque) w, "Worker Process", &pid); #endif if (code) { afs_com_err(whoami, code, "can't create worker process"); return code; } } code = 0; /* last non-zero code encountered */ #ifdef AFS_PTHREAD_ENV pthread_mutex_lock(&workerLock); #endif while (workers) { struct worker *w, *prevW, *nextW; prevW = 0; for (w = workers; w; w = nextW) { nextW = w->next; if (w->exitCode != RXKST_PROCESSRUNNING) { if (w->exitCode) { if (code == 0) code = w->exitCode; } if (prevW) prevW->next = w->next; else workers = w->next; osi_Free(w, sizeof(*w)); continue; /* don't bump prevW */ } prevW = w; } #ifdef AFS_PTHREAD_ENV if (workers) pthread_cond_wait(&workerCV, &workerLock); #else if (workers) LWP_WaitProcess(&workers); #endif } #ifdef AFS_PTHREAD_ENV pthread_mutex_unlock(&workerLock); #endif return code; }
void main(int ac, char **av) { int delay = 0; int iters = 0; int inter = 0; int line = 0; int i; PROCESS dotpid; int rc; for (i = 1; i < ac; i++) { if (!strcmp("-delay", av[i])) { if (++i >= ac) { printf("Missing delay time for -delay option.\n"); } delay = atoi(av[i]); if (delay < 0) { printf("Delay must be at least 0 seconds.\n"); Usage(); } } else if (!strcmp("-iters", av[i])) { if (++i >= ac) { printf("Missing iteration count for -iters option.\n"); } iters = atoi(av[i]); if (iters < 0) { printf("Number of iterations must be at least 0.\n"); Usage(); } } else if (!strcmp("-nobuf", av[i])) { rc = setvbuf(stdin, NULL, _IONBF, 0); if (rc < 0) { perror("Setting -nobuf for stdin"); } } else if (!strcmp("-inter", av[i])) { inter = 1; } else if (!strcmp("-line", av[i])) { line = 1; } else Usage(); } IOMGR_Initialize(); LWP_CreateProcess(DotWriter, 32000, LWP_NORMAL_PRIORITY, (char *)0, "DotWriter", &dotpid); if (inter) { interTest(); exit(1); } if (line) { lineTest(); exit(1); } if (delay == 0) { delay = -1; /* Means wait indefinitely. */ } for (; iters >= 0; iters--) { waitingForAnswer = 1; LWP_NoYieldSignal(&waitingForAnswer); rc = LWP_WaitForKeystroke(delay); waitingForAnswer = 0; if (rc) { printf("\n'%c'\n", getchar()); printf("Flushing remaining input.\n"); while (LWP_WaitForKeystroke(0)) { printf("'%c'\n", getchar()); } } else { printf("\nNo data available on this iteration.\n"); } } }
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); }