static int query(const char *domain, int type, int flags, cell_db_entry *dbservers, int max_num, int *ret_num, int *lowest_ttl) { struct ko_dns_query q; q.domain = domain; q.flags = flags & (CELL_QUERY|HOST_QUERY); q.dbservers = dbservers; q.max_num = max_num; if (type & CELL_QUERY) q.dbnum = 0; else q.dbnum = max_num; if (lowest_ttl) q.lowest_ttl = *lowest_ttl; IOMGR_Cancel(ares_pid); ares_query(achannel, domain, C_IN, type, callback, &q); while((q.flags & QUERY_DONE) == 0) LWP_WaitProcess(&q); if (lowest_ttl) *lowest_ttl = q.lowest_ttl; if (ret_num) *ret_num = q.dbnum; return q.error; }
/* wait until bnode status is correct */ int bnode_WaitStatus(struct bnode *abnode, int astatus) { afs_int32 code; afs_int32 stat; bnode_Hold(abnode); while (1) { /* get the status */ code = BOP_GETSTAT(abnode, &stat); if (code) return code; /* otherwise, check if we're done */ if (stat == astatus) { bnode_Release(abnode); return 0; /* done */ } if (astatus != abnode->goal) { bnode_Release(abnode); return -1; /* no longer our goal, don't keep waiting */ } /* otherwise, block */ abnode->flags |= BNODE_WAIT; LWP_WaitProcess(abnode); } }
static void heapcleaner (char *arg) { const void *head; struct timeval tv; while (1) { while ((head = heap_head (heap_ccpairs)) == NULL) LWP_WaitProcess (heap_ccpairs); while ((head = heap_head (heap_ccpairs)) != NULL) { struct ropa_ccpair *cc = (struct ropa_ccpair *)head; gettimeofday (&tv, NULL); if (tv.tv_sec < cc->expire) { unsigned long t = cc->expire - tv.tv_sec; IOMGR_Sleep (t); } else { /* XXX should this be fixed? listdel (cc->cb->ccpairs, cc->cb_li); cc->cb_li = NULL; */ break_ccpair (cc, TRUE); /* will remove it from the heap */ } } } }
afs_int32 canWrite(int fid) { #ifndef AFS_PTHREAD_ENV afs_int32 code = 0; #endif extern dumpSyncP dumpSyncPtr; ObtainWriteLock(&dumpSyncPtr->ds_lock); /* let the pipe drain */ while (dumpSyncPtr->ds_bytes > 0) { if (dumpSyncPtr->ds_readerStatus == DS_WAITING) { dumpSyncPtr->ds_readerStatus = 0; #ifdef AFS_PTHREAD_ENV CV_BROADCAST(&dumpSyncPtr->ds_readerStatus_cond); #else code = LWP_SignalProcess(&dumpSyncPtr->ds_readerStatus); if (code) LogError(code, "canWrite: Signal delivery failed\n"); #endif } dumpSyncPtr->ds_writerStatus = DS_WAITING; ReleaseWriteLock(&dumpSyncPtr->ds_lock); #ifdef AFS_PTHREAD_ENV MUTEX_ENTER(&dumpSyncPtr->ds_writerStatus_mutex); CV_WAIT(&dumpSyncPtr->ds_writerStatus_cond, &dumpSyncPtr->ds_writerStatus_mutex); MUTEX_EXIT(&dumpSyncPtr->ds_writerStatus_mutex); #else LWP_WaitProcess(&dumpSyncPtr->ds_writerStatus); #endif ObtainWriteLock(&dumpSyncPtr->ds_lock); } return (1); }
/* wait for all bnodes to stabilize */ int bnode_WaitAll(void) { struct bnode *tb; afs_int32 code; afs_int32 stat; retry: for (tb = allBnodes; tb; tb = tb->next) { bnode_Hold(tb); code = BOP_GETSTAT(tb, &stat); if (code) { bnode_Release(tb); return code; } if (stat != tb->goal) { tb->flags |= BNODE_WAIT; LWP_WaitProcess(tb); bnode_Release(tb); goto retry; } bnode_Release(tb); } return 0; }
void Lock_Obtain(struct Lock *lock, int how) { switch (how) { case READ_LOCK: lock->num_waiting++; do { lock -> wait_states |= READ_LOCK; LWP_WaitProcess(&lock->readers_reading); } while (lock->excl_locked & WRITE_LOCK); lock->num_waiting--; lock->readers_reading++; break; case WRITE_LOCK: lock->num_waiting++; do { lock -> wait_states |= WRITE_LOCK; LWP_WaitProcess(&lock->excl_locked); } while (lock->excl_locked || lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; case SHARED_LOCK: lock->num_waiting++; do { lock->wait_states |= SHARED_LOCK; LWP_WaitProcess(&lock->excl_locked); } while (lock->excl_locked); lock->num_waiting--; lock->excl_locked = SHARED_LOCK; break; case BOOSTED_LOCK: lock->num_waiting++; do { lock->wait_states |= WRITE_LOCK; LWP_WaitProcess(&lock->excl_locked); } while (lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; default: printf("Can't happen, bad LOCK type: %d\n", how); abort(); } }
static int DotWriter(char *junk) { while (1) { LWP_WaitProcess(&waitingForAnswer); PrintDots(); } return 0; }
static void Consumer(void *foo) { LWP_NoYieldSignal ((char *)Producer); while (1) { LWP_WaitProcess((char *)Consumer); printf("[consumer] eating %c\n", pcfoo); LWP_NoYieldSignal ((char *)Producer); } }
static void Producer(void *foo) { while (1) { LWP_WaitProcess((char *)Producer); pcfoo++; if (pcfoo > 'z') pcfoo = 'a'; printf("[producer] creating %c\n", pcfoo); LWP_NoYieldSignal ((char *)Consumer); } }
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 (); }
BbufStatus bbuf::remove(bbuf_item *result) { int sigResult; ObtainWriteLock(&lock); while (count <= low_fuel_mark) { ReleaseWriteLock(&lock); LWP_WaitProcess(low_fuel); ObtainWriteLock(&lock); } *result = buf[head++]; head = head % bnd; count--; sigResult = LWP_SignalProcess(full_tank); if ((sigResult != LWP_SUCCESS) && (sigResult != LWP_ENOWAIT)) bbuf_error("bbuf->remove():", sigResult); ReleaseWriteLock(&lock); return BBUFOK; }
void rpc2_ClockTick(void *dummy) {/* Non terminating LWP */ struct SL_Entry *sl; struct timeval tval; long timenow; int ticks = 0; sl = rpc2_AllocSle(OTHER, NULL); tval.tv_sec = TICKINTERVAL; tval.tv_usec = 0; while (TRUE) { /* ask for SocketListener to wake me up after TICKINTERVAL seconds */ rpc2_ActivateSle(sl, &tval); LWP_WaitProcess((char *)sl); LUA_clocktick(); /* only reap connections once a minute */ if ((ticks++ % 12) != 0) continue; timenow = rpc2_time(); say(1, RPC2_DebugLevel, "Clock Tick at %ld\n", timenow); #ifdef RPC2DEBUG if (RPC2_Trace && rpc2_TraceBuffHeader) { struct TraceElem *te; struct te_CLOCKTICK *tea; te = (struct TraceElem *)CBUF_NextSlot(rpc2_TraceBuffHeader); tea = &te->Args.ClockTickEntry; te->CallCode = CLOCKTICK; strncpy(te->ActiveLWP, LWP_Name(), sizeof(te->ActiveLWP)-1); tea->TimeNow = timenow; /* structure assignment */ } #endif /* and free up `dead' connections */ if (RPC2_enableReaping) rpc2_ReapDeadConns(); } }
void doneWriting(afs_int32 error) { #ifndef AFS_PTHREAD_ENV afs_int32 code = 0; #endif /* wait for the reader */ ObtainWriteLock(&dumpSyncPtr->ds_lock); while (dumpSyncPtr->ds_readerStatus != DS_WAITING) { LogDebug(4, "doneWriting: waiting for Reader\n"); dumpSyncPtr->ds_writerStatus = DS_WAITING; ReleaseWriteLock(&dumpSyncPtr->ds_lock); #ifdef AFS_PTHREAD_ENV MUTEX_ENTER(&dumpSyncPtr->ds_writerStatus_mutex); CV_WAIT(&dumpSyncPtr->ds_writerStatus_cond, &dumpSyncPtr->ds_writerStatus_mutex); MUTEX_EXIT(&dumpSyncPtr->ds_writerStatus_mutex); #else LWP_WaitProcess(&dumpSyncPtr->ds_writerStatus); #endif ObtainWriteLock(&dumpSyncPtr->ds_lock); } LogDebug(4, "doneWriting: setting done\n"); /* signal that we are done */ if (error) dumpSyncPtr->ds_writerStatus = DS_DONE_ERROR; else dumpSyncPtr->ds_writerStatus = DS_DONE; dumpSyncPtr->ds_readerStatus = 0; #ifdef AFS_PTHREAD_ENV CV_BROADCAST(&dumpSyncPtr->ds_readerStatus_cond); #else code = LWP_NoYieldSignal(&dumpSyncPtr->ds_readerStatus); if (code) LogError(code, "doneWriting: Signal delivery failed\n"); #endif ReleaseWriteLock(&dumpSyncPtr->ds_lock); }
BbufStatus bbuf::insert(bbuf_item to_insert) { int sigResult; ObtainWriteLock(&lock); while (count == bnd) { ReleaseWriteLock(&lock); LWP_WaitProcess(full_tank); ObtainWriteLock(&lock); } buf[tail++] = to_insert; tail = tail % bnd; count++; if (count > low_fuel_mark) { sigResult = LWP_SignalProcess(low_fuel); if ((sigResult != LWP_SUCCESS) && (sigResult != LWP_ENOWAIT)) { bbuf_error("bbuf->insert():", sigResult); } } ReleaseWriteLock(&lock); return BBUFOK; }
int main(void) { long go; GetRoot(); /* Also creates a child process for transcribing stdout */ GetParms(); MakeFiles(); /* in test directory */ InitRPC(); MakeWorkers(); GetConns(); GetVar(&go, "Say when: "); DoBindings(); MakeClients(); /* wait for all clients to get ready */ while (ClientsReady < Clients) LWP_DispatchProcess(); LWP_NoYieldSignal((char *)&ClientsReady); LWP_WaitProcess((char *)main); /* infinite wait */ return 0; /* make compiler happy */ }
void BrainSurgeon() { bool rc; LogMsg(1000,LogLevel,LogFile,"Starting Brain Surgeon thread"); if (lobotomy == mfalse) LWP_WaitProcess(DoLobotomy); /* we only get here if a lobotomy has been arranged */ LogMsg(0,LogLevel,LogFile, "***** Lobotomizing"); extern bbuf *buffer; buffer->flush_the_tank(); while((rc = buffer->empty()) != mtrue) { LWP_DispatchProcess(); } /* ** if we've gotten here, we know that no new requests have ** entered the buffer, and the buffer is empty, so die ** gracefully. */ Data_Done(); Log_Done(); RestoreSignals(); exit(0); }
void handleRequest(char *arg) { clientHandle_t *ch = (clientHandle_t *) arg; selcmd_t sc; struct stat sbuf; int code = 0; int c_errno = 0; while (1) { Log("(handleRequest) going to sleep on 0x%x\n", &ch->ch_state); LWP_WaitProcess(&ch->ch_state); assert(ch->ch_state == CH_INUSE); FD_ZERO(&(ch->ch_read)); FD_ZERO(&(ch->ch_write)); FD_ZERO(&(ch->ch_except)); FD_SET(ch->ch_fd, &(ch->ch_read)); FD_SET(ch->ch_fd, &(ch->ch_except)); code = IOMGR_Select(ch->ch_fd + 1, &(ch->ch_read), &(ch->ch_write), &(ch->ch_except), (struct timeval *)NULL); if (FD_ISSET(ch->ch_fd, &(ch->ch_except))) { Log("Received expception. Read fd_set shows %d\n", FD_ISSET(ch->ch_fd, &(ch->ch_read))); assertNullFDSet(ch->ch_fd, &(ch->ch_read)); assertNullFDSet(-1, &(ch->ch_write)); assertNullFDSet(ch->ch_fd, &(ch->ch_except)); goto done; } assert(code > 0); if (read(ch->ch_fd, (char *)&sc, sizeof(sc)) != sizeof(sc)) { Die(1, "(handleRequest) read command"); } Log("(handleRequest)cmd=%d\n", sc.sc_cmd); fflush(stdout); switch (sc.sc_cmd) { case SC_PROBE: Log("Probed from client at %s\n", inet_ntoa(ch->ch_addr.sin_addr)); break; #ifdef notdef case SC_OOB: nThreads--; ch->ch_fd = 0; ch->ch_state = CH_FREE; return; #endif case SC_WRITE: handleWrite(ch, &sc); break; case SC_END: Log("Ending ungracefully in server.\n"); exit(1); default: Log("%d: bad command to handleRequest.\n", sc.sc_cmd); break; } done: /* We're done now, so we can be re-used. */ nThreads--; close(ch->ch_fd); ch->ch_fd = 0; ch->ch_state = CH_FREE; } }
static struct ropa_client * client_query (uint32_t host, uint16_t port) { struct ropa_client *c, *c_new; int ret; c = client_query_notalkback(host, port); if (c == NULL) { interfaceAddr remote; struct rx_connection *conn = NULL; c = obtain_client(); assert (c->state == ROPAC_FREE && c->li == NULL); c->state = ROPAC_LOOKUP_U; c->flags |= ROPAF_LOOKUP; client_init (c, host, port, NULL, NULL); conn = rx_NewConnection (host, port, CM_SERVICE_ID, rxnull_NewClientSecurityObject(), 0); if (conn == NULL) { free(c); return NULL; } retry: switch (c->state) { case ROPAC_DEAD: c->li = listaddtail (lru_clients, c); ret = ENETDOWN; break; case ROPAC_LOOKUP_U: ret = RXAFSCB_WhoAreYou (conn, &remote); if (ret == RXGEN_OPCODE) { c->state = ROPAC_LOOKUP; goto retry; } else if (ret == RX_CALL_DEAD) { c->state = ROPAC_DEAD; goto retry; } else { struct ropa_client ckey; ckey.uuid = remote.uuid; c_new = hashtabsearch (ht_clients_uuid, &ckey); if (c_new == NULL) { client_init (c, host, port, &remote.uuid, NULL); ret = RXAFSCB_InitCallBackState3(conn, &server_uuid); } else { client_update_interfaces (c_new, host, port, &remote); disconnect_client (c); c = c_new; listdel(lru_clients, c->li); c->li = NULL; } } break; case ROPAC_LOOKUP: { afsUUID uuid; ret = RXAFSCB_InitCallBackState(conn); if (ret == RX_CALL_DEAD) { c->state = ROPAC_DEAD; goto retry; } uuid_init_simple (&uuid, host); client_init (c, host, port, &uuid, NULL); break; } default: exit(-1); } rx_DestroyConnection (conn); if ((c->flags & ROPAF_WAITING) != 0) LWP_NoYieldSignal (c); c->flags &= ~(ROPAF_LOOKUP|ROPAF_WAITING); if (ret) { assert (c->li != NULL); return NULL; } assert (c->li == NULL); c->li = listaddhead (lru_clients, c); } else { /* c != NULL */ if ((c->flags & ROPAF_LOOKUP) != 0) { c->flags |= ROPAF_WAITING; LWP_WaitProcess (c); } assert (c->li != NULL); } return c; }
void Afs_Lock_Obtain(struct Lock *lock, int how) { switch (how) { case READ_LOCK: lock->num_waiting++; do { lock->wait_states |= READ_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->read_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->readers_reading); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked & WRITE_LOCK); lock->num_waiting--; lock->readers_reading++; break; case WRITE_LOCK: lock->num_waiting++; do { lock->wait_states |= WRITE_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked || lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; case SHARED_LOCK: lock->num_waiting++; do { lock->wait_states |= SHARED_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->excl_locked); lock->num_waiting--; lock->excl_locked = SHARED_LOCK; break; case BOOSTED_LOCK: lock->num_waiting++; do { lock->wait_states |= WRITE_LOCK; #ifdef AFS_PTHREAD_ENV opr_Verify(pthread_cond_wait(&lock->write_cv, &lock->mutex) == 0); #else /* AFS_PTHREAD_ENV */ LWP_WaitProcess(&lock->excl_locked); #endif /* AFS_PTHREAD_ENV */ } while (lock->readers_reading); lock->num_waiting--; lock->excl_locked = WRITE_LOCK; break; default: printf("Can't happen, bad LOCK type: %d\n", how); opr_Assert(0); } }
/* release a write lock and sleep on an address, atomically */ void LWP_WaitProcessS(void *addr, struct Lock *alock) { ReleaseSharedLock(alock); LWP_WaitProcess(addr); }
static void pinger (char *arg) { for (;;) { struct timeval tv; Listitem *item; ConnCacheEntry *e; struct in_addr addr; const char *port_str; arla_warnx(ADEBCONN, "running pinger"); while (listemptyp (connprobelist)) LWP_WaitProcess (connprobelist); item = listhead (connprobelist); e = (ConnCacheEntry *)listdata (item); assert (e->probe_le == item); gettimeofday (&tv, NULL); if (tv.tv_sec < e->probe_next) { unsigned long t = e->probe_next - tv.tv_sec; arla_warnx(ADEBCONN, "pinger: sleeping %lu second(s)", t); IOMGR_Sleep (t); continue; } listdel (connprobelist, item); e->probe_le = NULL; if (e->flags.alivep) continue; addr.s_addr = e->host; port_str = ports_num2name (e->port); if (port_str != NULL) arla_warnx (ADEBCONN, "pinger: probing %s/%s", inet_ntoa(addr), port_str); else arla_warnx (ADEBCONN, "pinger: probing %s/%d", inet_ntoa(addr), e->port); ++e->refcount; if (e->probe == NULL) arla_warnx(ADEBWARN, "pinger: probe function is NULL, " "host: %s cell: %d port: %d", inet_ntoa(addr), e->cell, e->port); if (connected_mode == DISCONNECTED) { arla_warnx(ADEBCONN, "pinger: ignoring host in disconnected mode"); } else if (e->probe && ((*(e->probe))(e->connection) == 0)) { conn_alive (e); } else { re_probe (e); } conn_free (e); } }
/* release a write lock and sleep on an address, atomically */ void LWP_WaitProcessW(register void *addr, register struct Lock *alock) { ReleaseWriteLock(alock); LWP_WaitProcess(addr); }
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 */ }
/* release a write lock and sleep on an address, atomically */ void LWP_WaitProcessS(register void *addr, register struct Lock *alock) { ReleaseSharedLock(alock); LWP_WaitProcess(addr); }
static void ClientBody(void *arg) { RPC2_Handle thisconn; RPC2_Integer thisopcode; RPC2_PacketBuffer *request, *reply; long retcode, rpctime = 0; struct timeval t1, t2; char myprivatefile[256]; char myhashmark; RPC2_BindParms bp; SE_Descriptor sed; #define MakeTimedCall(whichse)\ if (VerboseFlag) gettimeofday(&t1, 0);\ retcode = RPC2_MakeRPC(ConnVector[thisconn].ConnHandle, request, whichse, &reply, NULL, 0);\ if (VerboseFlag) gettimeofday(&t2, 0);\ if (VerboseFlag) rpctime = ((t2.tv_sec - t1.tv_sec)*1000) + ((t2.tv_usec - t1.tv_usec)/1000); memset(&sed, 0, sizeof(SE_Descriptor)); sed.Tag = SMARTFTP; strcpy(myprivatefile, MakeName(LWP_Name())); myhashmark = NextHashMark++; LWP_DispatchProcess(); /* initial courtesy to parent */ RPC2_AllocBuffer(1000, &request); reply = NULL; ClientsReady++; LWP_WaitProcess((char *)&ClientsReady); /* wait for main() to tap me on shoulder */ while(1) { if (reply) RPC2_FreeBuffer(&reply); RanDelay(MaxThinkTime); SelectParms(&thisconn, &thisopcode); ConnVector[thisconn].Status = BUSY; request->Header.Opcode = thisopcode; if (VerboseFlag) fprintf(stderr, "Making request %d to %s for %s\n", thisopcode, ConnVector[thisconn].RemoteHost.Value.Name, ConnVector[thisconn].NameBuf); switch(thisopcode) { case 1: /* return Unix epoch time */ { request->Header.BodyLength = 0; MakeTimedCall(NULL); if (retcode == RPC2_SUCCESS) { if (VerboseFlag) fprintf(stderr, "Time on %s is %s (%ld msecs)\n", ConnVector[thisconn].RemoteHost.Value.Name, reply->Body, rpctime); break; } else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); } case 2: /* square the input integer */ { uint32_t *op = (uint32_t *)request->Body; uint32_t x = (uint32_t)random() % 100; op[0] = htonl(x); request->Header.BodyLength = sizeof(uint32_t); MakeTimedCall(NULL); if (retcode == RPC2_SUCCESS) { if (VerboseFlag) { uint32_t *ip = (uint32_t *)reply->Body; fprintf(stderr, " %s says square of %u is %u (%ld msecs)\n", ConnVector[thisconn].RemoteHost.Value.Name, x, ntohl(ip[0]), rpctime); } break; } else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); break; } case 3: /* cube the input integer */ { uint32_t *op = (uint32_t *)request->Body; uint32_t x = (uint32_t)random() % 100; op[0] = htonl(x); request->Header.BodyLength = sizeof(uint32_t); MakeTimedCall(NULL); if (retcode == RPC2_SUCCESS) { if (VerboseFlag) { uint32_t *ip = (uint32_t *)reply->Body; fprintf(stderr, "%s says cube of %d is %u (%ld msecs)\n", ConnVector[thisconn].RemoteHost.Value.Name, x, ntohl(ip[0]), rpctime); } break; } else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); break; } case 4: /* Return your machine name */ { request->Header.BodyLength = 0; MakeTimedCall(NULL); if (retcode == RPC2_SUCCESS) { if (VerboseFlag) fprintf(stderr, "%s says its name is \"%s\" (%ld msecs)\n", ConnVector[thisconn].RemoteHost.Value.Name, reply->Body, rpctime); break; } else HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); break; } case 5: /* Fetch a random file */ { if (AvoidBulk) { ConnVector[thisconn].Status = SFREE; continue; } request->Header.BodyLength = 0; sed.Value.SmartFTPD.TransmissionDirection = SERVERTOCLIENT; sed.Value.SmartFTPD.FileInfo.ByName.ProtectionBits = 0644; sed.Value.SmartFTPD.SeekOffset = 0; sed.Value.SmartFTPD.Tag = FILEBYNAME; strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName, myprivatefile); if (VerboseFlag) sed.Value.SmartFTPD.hashmark = myhashmark; else sed.Value.SmartFTPD.hashmark = 0; MakeTimedCall(&sed); if (retcode != RPC2_SUCCESS) { HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); break; } else if (VerboseFlag) fprintf(stderr, "%ld bytes transferred\n", sed.Value.SmartFTPD.BytesTransferred); break; } case 6: /* Store a random file */ { uint32_t randval; if (AvoidBulk) { ConnVector[thisconn].Status = SFREE; continue; } request->Header.BodyLength = 0; sed.Value.SmartFTPD.TransmissionDirection = CLIENTTOSERVER; sed.Value.SmartFTPD.SeekOffset = 0; sed.Value.SmartFTPD.Tag = FILEBYNAME; randval = (uint32_t)random(); strcpy(sed.Value.SmartFTPD.FileInfo.ByName.LocalFileName, SysFiles[randval % SysFileCount]); if (VerboseFlag) sed.Value.SmartFTPD.hashmark = myhashmark; else sed.Value.SmartFTPD.hashmark = 0; MakeTimedCall(&sed); if (retcode != RPC2_SUCCESS) { HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); break; } else if (VerboseFlag) fprintf(stderr, "%ld bytes transferred\n", sed.Value.SmartFTPD.BytesTransferred); break; } case 7: /* Unbind */ { request->Header.BodyLength = 0; MakeTimedCall(NULL); if (retcode == RPC2_SUCCESS) { if (VerboseFlag) fprintf(stderr, "Unbound connection to %s for %s after %ld calls\n", ConnVector[thisconn].RemoteHost.Value.Name, ConnVector[thisconn].Identity.SeqBody, ConnVector[thisconn].CallsMade); assert(RPC2_Unbind(ConnVector[thisconn].ConnHandle) == RPC2_SUCCESS); } else {HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode));} ConnVector[thisconn].Status = UNBOUND; break; } case 8: /* Rebind */ { bp.SecurityLevel = ConnVector[thisconn].SecurityLevel; bp.EncryptionType = RPC2_XOR; bp.SideEffectType = SMARTFTP; bp.ClientIdent = &ConnVector[thisconn].Identity; bp.SharedSecret = &ConnVector[thisconn].Password; retcode = RPC2_NewBinding(&ConnVector[thisconn].RemoteHost, &PortId, &SubsysId, &bp, &ConnVector[thisconn].ConnHandle); if (retcode < RPC2_ELIMIT) { HandleRPCFailure(thisconn, retcode, ntohl(request->Header.Opcode)); } else { if (VerboseFlag) fprintf(stderr, "Rebound connection to %s for %s\n", ConnVector[thisconn].RemoteHost.Value.Name, ConnVector[thisconn].Identity.SeqBody); } break; } case 999: /* Quit */ { } default: /* unknown opcode */ printf("Arrrgggghhh .... bogus opcode\n"); abort(); break; } if (ConnVector[thisconn].Status == BUSY) ConnVector[thisconn].Status = SFREE; if (retcode == RPC2_CONNBUSY) continue; /* you didn't really do it */ /* Indicate progress */ ConnVector[thisconn].CallsMade++; if(ConnVector[thisconn].CallsMade % Announce == 1) { struct CVEntry *ce = &ConnVector[thisconn]; printf("\n%ld successful calls to %s for %s at %s", ce->CallsMade, ce->RemoteHost.Value.Name, ce->NameBuf, TimeNow()); PrintStats(); } else { int xx; xx = (1.0*Announce)/100.0 + 0.5; /* ceiling */ if (xx == 0 || ConnVector[thisconn].CallsMade % xx == 1) printf("%c", myhashmark); } } }
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); }
/* release a write lock and sleep on an address, atomically */ void LWP_WaitProcessR(void *addr, struct Lock *alock) { ReleaseReadLock(alock); LWP_WaitProcess(addr); }
/* release a write lock and sleep on an address, atomically */ void LWP_WaitProcessW(void *addr, struct Lock *alock) { ReleaseWriteLock(alock); LWP_WaitProcess(addr); }
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; }
/* * Sleep on the unique wait channel provided. */ void rxi_Sleep(void *addr) { LWP_WaitProcess(addr); }