Пример #1
0
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;
}
Пример #2
0
/* 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);
    }
}
Пример #3
0
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 */
	    }
	}
    }
}
Пример #4
0
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);
}
Пример #5
0
/* 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;
}
Пример #6
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();
    }
}
Пример #7
0
static int
DotWriter(char *junk)
{
    while (1) {
	LWP_WaitProcess(&waitingForAnswer);
	PrintDots();
    }
    return 0;
}
Пример #8
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);
    }
}
Пример #9
0
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);
    }
}
Пример #10
0
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 ();
}
Пример #11
0
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;
}
Пример #12
0
Файл: ct.c Проект: jaharkes/coda
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();
    }
}
Пример #13
0
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);
}
Пример #14
0
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;
}
Пример #15
0
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 */
}
Пример #16
0
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);
}
Пример #17
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;
    }
}
Пример #18
0
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;
}
Пример #19
0
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);
    }
}
Пример #20
0
/* release a write lock and sleep on an address, atomically */
void
LWP_WaitProcessS(void *addr, struct Lock *alock)
{
    ReleaseSharedLock(alock);
    LWP_WaitProcess(addr);
}
Пример #21
0
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);
    }
}
Пример #22
0
/* 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);
}
Пример #23
0
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 */

}
Пример #24
0
/* 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);
}
Пример #25
0
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);
	    }
	
	}

}
Пример #26
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);
}
Пример #27
0
/* release a write lock and sleep on an address, atomically */
void
LWP_WaitProcessR(void *addr, struct Lock *alock)
{
    ReleaseReadLock(alock);
    LWP_WaitProcess(addr);
}
Пример #28
0
/* release a write lock and sleep on an address, atomically */
void
LWP_WaitProcessW(void *addr, struct Lock *alock)
{
    ReleaseWriteLock(alock);
    LWP_WaitProcess(addr);
}
Пример #29
0
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;
}
Пример #30
0
/*
 * Sleep on the unique wait channel provided.
 */
void
rxi_Sleep(void *addr)
{
    LWP_WaitProcess(addr);
}