Exemple #1
0
unsigned long main_Mod1(void *parm)
{
	long i;
	for(i=0; i<OSI_MOD1LOOPS; i++) {
		lock_ObtainMutex(&main_aMutex);
		osi_Log0(main_logp, "mod1");
		lock_ObtainWrite(&main_bRWLock);
		a -= 52;
		Sleep(0);
		b += 52;
		osi_assert(a+b == 100);
		Sleep(0);
		lock_ReleaseWrite(&main_bRWLock);
		Sleep(0);
		lock_ReleaseMutex(&main_aMutex);
		Sleep(0);
		m1Loops = i;
                osi_Log1(main_logp, "mod1 done, %d", m1Loops);
	}
	lock_ObtainWrite(&main_doneRWLock);
	done++;
	Sleep(0);
	lock_ReleaseWrite(&main_doneRWLock);
	return 0;
}
Exemple #2
0
/* newCellNamep is required to be CELL_MAXNAMELEN in size */
long cm_SearchCellByDNS(char *cellNamep, char *newCellNamep, int *ttl,
                        cm_configProc_t *procp, void *rockp)
{
    int rc;
    int  cellHostAddrs[AFSMAXCELLHOSTS];
    char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
    unsigned short ipRanks[AFSMAXCELLHOSTS];
    unsigned short ports[AFSMAXCELLHOSTS];      /* network byte order */
    int numServers;
    int i;
    struct sockaddr_in vlSockAddr;

#ifdef CELLSERV_DEBUG
    osi_Log1(afsd_logp,"SearchCellDNS-Doing search for [%s]", osi_LogSaveString(afsd_logp,cellNamep));
#endif
    /*
     * Do not perform a DNS lookup if the name is
     * either a well-known Windows DLL or directory,
     * or if the name does not contain a top-level
     * domain, or if the file prefix is the afs pioctl
     * file name.
     */
    if ( IsWindowsModule(cellNamep) ||
         cm_FsStrChr(cellNamep, '.') == NULL ||
         strncasecmp(cellNamep, CM_IOCTL_FILENAME_NOSLASH, sizeof(CM_IOCTL_FILENAME_NOSLASH)-1) == 0)
	return -1;

    rc = getAFSServer("afs3-vlserver", "udp", cellNamep, htons(7003),
                      cellHostAddrs, cellHostNames, ports, ipRanks, &numServers, ttl);
    if (rc == 0 && numServers > 0) {     /* found the cell */
        for (i = 0; i < numServers; i++) {
            memcpy(&vlSockAddr.sin_addr.s_addr, &cellHostAddrs[i],
                   sizeof(long));
            vlSockAddr.sin_port = ports[i];
            vlSockAddr.sin_family = AF_INET;
            if (procp)
                (*procp)(rockp, &vlSockAddr, cellHostNames[i], ipRanks[i]);
        }
        if (newCellNamep) {
            if(FAILED(StringCchCopy(newCellNamep, CELL_MAXNAMELEN, cellNamep)))
                return -1;
            strlwr(newCellNamep);
        }
        return 0;   /* found cell */
    }
    else
       return -1;  /* not found */
}
Exemple #3
0
void cm_BkgDaemon(void * parm)
{
    cm_bkgRequest_t *rp;
    afs_int32 code;
    char name[32] = "";
    long daemonID = (long)parm;

    snprintf(name, sizeof(name), "cm_BkgDaemon_ShutdownEvent%d", daemonID);

    cm_BkgDaemon_ShutdownEvent[daemonID] = thrd_CreateEvent(NULL, FALSE, FALSE, name);
    if ( GetLastError() == ERROR_ALREADY_EXISTS )
        afsi_log("Event Object Already Exists: %s", name);

    rx_StartClientThread();

    lock_ObtainWrite(&cm_daemonLock);
    while (daemon_ShutdownFlag == 0) {
        if (powerStateSuspended) {
            Sleep(1000);
            continue;
        }
        if (!cm_bkgListEndp) {
            osi_SleepW((LONG_PTR)&cm_bkgListp, &cm_daemonLock);
            lock_ObtainWrite(&cm_daemonLock);
            continue;
        }
                
        /* we found a request */
        for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q))
	{
	    if (cm_ServerAvailable(&rp->scp->fid, rp->userp) && 
                !(rp->scp->flags & CM_SCACHEFLAG_DATASTORING))
		break;
	}
	if (rp == NULL) {
	    /* we couldn't find a request that we could process at the current time */
	    lock_ReleaseWrite(&cm_daemonLock);
	    Sleep(1000);
	    lock_ObtainWrite(&cm_daemonLock);
	    continue;
	}

        osi_QRemoveHT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **) &cm_bkgListEndp, &rp->q);
        osi_assertx(cm_bkgQueueCount-- > 0, "cm_bkgQueueCount 0");
        lock_ReleaseWrite(&cm_daemonLock);

	osi_Log1(afsd_logp,"cm_BkgDaemon processing request 0x%p", rp);

#ifdef DEBUG_REFCOUNT
	osi_Log2(afsd_logp,"cm_BkgDaemon (before) scp 0x%x ref %d",rp->scp, rp->scp->refCount);
#endif
        code = (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp);
#ifdef DEBUG_REFCOUNT                
	osi_Log2(afsd_logp,"cm_BkgDaemon (after) scp 0x%x ref %d",rp->scp, rp->scp->refCount);
#endif

        /*
         * Keep the following list synchronized with the
         * error code list in cm_BkgStore.  
         * cm_SyncOpDone(CM_SCACHESYNC_ASYNCSTORE) will be called there unless
         * one of these errors has occurred.
         */
        switch ( code ) {
        case CM_ERROR_TIMEDOUT:	/* or server restarting */
        case CM_ERROR_RETRY:
        case CM_ERROR_WOULDBLOCK:
        case CM_ERROR_ALLBUSY:
        case CM_ERROR_ALLDOWN:
        case CM_ERROR_ALLOFFLINE:
        case CM_ERROR_PARTIALWRITE:
            if (rp->procp == cm_BkgStore) {
                osi_Log2(afsd_logp,
                         "cm_BkgDaemon re-queueing failed request 0x%p code 0x%x",
                         rp, code);
                lock_ObtainWrite(&cm_daemonLock);
                cm_bkgQueueCount++;
                osi_QAddT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **)&cm_bkgListEndp, &rp->q);
                break;
            } /* otherwise fall through */
        case 0:  /* success */
        default: /* other error */
            if (code == 0)
                osi_Log1(afsd_logp,"cm_BkgDaemon SUCCESS: request 0x%p", rp);
            else
                osi_Log2(afsd_logp,"cm_BkgDaemon FAILED: request dropped 0x%p code 0x%x",
                         rp, code);
            cm_ReleaseUser(rp->userp);
            cm_ReleaseSCache(rp->scp);
            free(rp);
            lock_ObtainWrite(&cm_daemonLock);
        }
    }
    lock_ReleaseWrite(&cm_daemonLock);
    thrd_SetEvent(cm_BkgDaemon_ShutdownEvent[daemonID]);
}
Exemple #4
0
afs_int32
smb_RPCNmpipeTransact(smb_fid_t *fidp, smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
    smb_tran2Packet_t *outp = NULL;
    struct smb_rpc *rpcp;
    afs_int32 code = 0;
    cm_user_t * userp = NULL;
    smb_user_t * uidp = NULL;
    int len;

    osi_Log0(smb_logp, "smb_RPCNmpipeTransact() begin");

    uidp = smb_FindUID(vcp, p->uid, 0);
    if (!uidp)
	return CM_ERROR_BADSMB;
    userp = smb_GetUserFromUID(uidp);
    osi_assertx(userp != NULL, "null cm_user_t");

    if (uidp && uidp->unp) {
        osi_Log3(afsd_logp, "RPC Transact uid %d user %x name %S",
		 uidp->userID, userp,
		 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
    } else {
        if (uidp)
	    osi_Log2(afsd_logp, "RPC Transact uid %d user %x no name",
                     uidp->userID, userp);
        else
	    osi_Log1(afsd_logp, "RPC Transact no uid user %x no name",
		     userp);
    }

    lock_ObtainMutex(&fidp->mx);
    rpcp = fidp->rpcp;
    code = smb_RPC_BeginOp(rpcp);

    if (code) {
	osi_Log0(smb_logp, "Can't begin RPC op.  Aborting");
	lock_ReleaseMutex(&fidp->mx);

	smb_ReleaseUID(uidp);
	cm_ReleaseUser(userp);
	return code;
    }

    osi_assertx((fidp->flags & SMB_FID_RPC), "FID wasn't setup for RPC");
    osi_assertx(fidp->rpcp, "smb_rpc_t not associated with RPC FID");

    lock_ReleaseMutex(&fidp->mx);

    code = smb_RPC_PrepareWrite(rpcp);
    if (code)
	goto done;

    code = smb_RPC_WritePacket(rpcp, p->datap, p->totalData, userp);
    if (code)
	goto done;

    code = smb_RPC_PrepareRead(rpcp);
    if (code)
	goto done;

    len = smb_RPC_ReadPacketLength(rpcp, p->maxReturnData);

    outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, len);
    if (len > 0) {
	code = smb_RPC_ReadPacket(rpcp, outp->datap, len);

	if (code == CM_ERROR_RPC_MOREDATA) {
	    outp->error_code = CM_ERROR_RPC_MOREDATA;
	}
    }

    if (code == 0 || code == CM_ERROR_RPC_MOREDATA)
	smb_SendTran2Packet(vcp, outp, op);
    smb_FreeTran2Packet(outp);

 done:
    smb_RPC_EndOp(rpcp);

    osi_Log1(smb_logp, "smb_RPCNmpipeTransact() end code=%d", code);

    if (uidp)
	smb_ReleaseUID(uidp);
    if (userp)
	cm_ReleaseUser(userp);

    return code;
}
Exemple #5
0
/**
   Handle SMB_COM_READ_ANDX for an RPC fid

   Called from smb_ReceiveV3ReadX to handle RPC descriptor reads */
afs_int32
smb_RPCV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
    smb_rpc_t *rpcp;
    long count;
    afs_int32 code;
    char *op;
    cm_user_t *userp;
    smb_user_t *uidp;

    count = smb_GetSMBParm(inp, 5);

    uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
    if (!uidp)
        return CM_ERROR_BADSMB;
    userp = smb_GetUserFromUID(uidp);
    osi_assertx(userp != NULL, "null cm_user_t");

    osi_Log3(smb_logp, "smb_RPCV3Read for user[0x%p] fid[0x%p (%d)]",
	     userp, fidp, fidp->fid);

    if (uidp && uidp->unp) {
        osi_Log3(afsd_logp, "RPC uid %d user %x name %S",
		 uidp->userID, userp,
		 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
    } else {
        if (uidp)
	    osi_Log2(afsd_logp, "RPC uid %d user %x no name",
                     uidp->userID, userp);
        else
	    osi_Log1(afsd_logp, "RPC no uid user %x no name",
		     userp);
    }

    lock_ObtainMutex(&fidp->mx);
    rpcp = fidp->rpcp;
    code = smb_RPC_BeginOp(rpcp);
    lock_ReleaseMutex(&fidp->mx);

    if (code) {
	if (uidp)
	    smb_ReleaseUID(uidp);
	cm_ReleaseUser(userp);
	return code;
    }

    code = smb_RPC_PrepareRead(rpcp);
    if (uidp) {
        smb_ReleaseUID(uidp);
    }
    if (code) {
	cm_ReleaseUser(userp);
	smb_RPC_EndOp(rpcp);
	return code;
    }

    count = smb_RPC_ReadPacketLength(rpcp, count);

    /* 0 and 1 are reserved for request chaining, were setup by our caller,
     * and will be further filled in after we return.
     */
    smb_SetSMBParm(outp, 2, 0);	/* remaining bytes, for pipes */
    smb_SetSMBParm(outp, 3, 0);	/* resvd */
    smb_SetSMBParm(outp, 4, 0);	/* resvd */
    smb_SetSMBParm(outp, 5, count);	/* # of bytes we're going to read */
    /* fill in #6 when we have all the parameters' space reserved */
    smb_SetSMBParm(outp, 7, 0);	/* resv'd */
    smb_SetSMBParm(outp, 8, 0);	/* resv'd */
    smb_SetSMBParm(outp, 9, 0);	/* resv'd */
    smb_SetSMBParm(outp, 10, 0);	/* resv'd */
    smb_SetSMBParm(outp, 11, 0);	/* reserved */

    /* get op ptr after putting in the last parm, since otherwise we don't
     * know where the data really is.
     */
    op = smb_GetSMBData(outp, NULL);

    /* now fill in offset from start of SMB header to first data byte (to op) */
    smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));

    /* set the packet data length the count of the # of bytes */
    smb_SetSMBDataLength(outp, count);

    smb_RPC_ReadPacket(rpcp, op, count);

    smb_RPC_EndOp(rpcp);

    /* and cleanup things */
    cm_ReleaseUser(userp);

    return 0;
}
Exemple #6
0
afs_int32
smb_RPC_ReadPacket(smb_rpc_t * rpcp, BYTE * buffer, afs_uint32 length)
{
    osi_Log1(smb_logp, "   RPC Read Packet for length %d", length);
    return MSRPC_ReadMessage(&rpcp->rpc_conn, buffer, length);
}
Exemple #7
0
/*
 * lock_ObtainMutex must be held prior to calling
 * this function.
 */
afs_int32
cm_RankServer(cm_server_t * tsp)
{
    afs_int32 code = 0; /* start with "success" */
    struct rx_debugPeer tpeer;
    struct rx_peer * rxPeer;
    afs_uint16 port;
    afs_uint64 newRank;
    afs_uint64 perfRank = 0;
    afs_uint64 rtt = 0;
    double log_rtt;

    int isDown = (tsp->flags & CM_SERVERFLAG_DOWN);
    void *peerRpcStats = NULL;
    afs_uint64 opcode = 0;

    switch(tsp->type) {
	case CM_SERVER_VLDB:
	    port = htons(7003);
            opcode = opcode_VL_ProbeServer;
	    break;
	case CM_SERVER_FILE:
	    port = htons(7000);
            opcode = opcode_RXAFS_GetCapabilities;
	    break;
	default:
	    return -1;
    }

    cm_SetServerIPRank(tsp);

    if (isDown) {
        newRank = 0xFFFF;
    } else {
        /*
        * There are three potential components to the ranking:
        *  1. Any administrative set preference whether it be
        *     via "fs setserverprefs", registry or dns.
        *
        *  2. Network subnet mask comparison.
        *
        *  3. Performance data.
        *
        * If there is an administrative rank, that is the
        * the primary factor.  If not the primary factor
        * is the network ranking.
        */

        code = rx_GetLocalPeers(tsp->addr.sin_addr.s_addr, port, &tpeer);
        if (code == 0) {
            peerRpcStats = rx_CopyPeerRPCStats(opcode, tsp->addr.sin_addr.s_addr, port);
            if (peerRpcStats == NULL && tsp->type == CM_SERVER_FILE)
                peerRpcStats = rx_CopyPeerRPCStats(opcode_RXAFS_GetTime, tsp->addr.sin_addr.s_addr, port);
            if (peerRpcStats) {
                afs_uint64 execTimeSum = _8THMSEC(RPCOpStat_ExecTimeSum(peerRpcStats));
                afs_uint64 queueTimeSum = _8THMSEC(RPCOpStat_QTimeSum(peerRpcStats));
                afs_uint64 numCalls = RPCOpStat_NumCalls(peerRpcStats);

                if (numCalls > 0)
                    rtt = (execTimeSum - queueTimeSum) / numCalls;

                rx_ReleaseRPCStats(peerRpcStats);
            }

            if (rtt == 0 && tpeer.rtt) {
                /* rtt is ms/8 */
                rtt = tpeer.rtt;
            }

            if (rtt > 0) {
                log_rtt = log(rtt);
                perfRank += (6000 * log_rtt / 5000) * 5000;

                if (tsp->type == CM_SERVER_FILE) {
                    /* give an edge to servers with high congestion windows */
                    perfRank -= (tpeer.cwind - 1)* 15;
                }
            }
        }

        if (tsp->adminRank) {
            newRank = tsp->adminRank * 0.8;
            newRank += tsp->ipRank * 0.2;
        } else {
            newRank = tsp->ipRank;
        }
        if (perfRank) {
            newRank *= 0.9;
            newRank += perfRank * 0.1;
        }
        newRank += (rand() & 0x000f); /* randomize */

        if (newRank > 0xFFFF)
            osi_Log1(afsd_logp, "new server rank %I64u exceeds 0xFFFF", newRank);

        /*
         * If the ranking changes by more than the randomization
         * factor, update the server reference lists.
         */
        if (abs(newRank - tsp->activeRank) > 0xf) {
            tsp->activeRank = newRank;

            lock_ReleaseMutex(&tsp->mx);
            switch (tsp->type) {
            case CM_SERVER_FILE:
                /*
                 * find volumes which might have RO copy
                 * on server and change the ordering of
                 * their RO list
                 */
                cm_ChangeRankVolume(tsp);
                break;
            case CM_SERVER_VLDB:
                /* set preferences for an existing vlserver */
                cm_ChangeRankCellVLServer(tsp);
                break;
            }
            lock_ObtainMutex(&tsp->mx);
        }
    }

    return code;
}