Exemple #1
0
int
main(int argc, char **argv)
{
    char *hostname;
    struct hostent *hostent;
    afs_uint32 host;
    int logstdout = 0;
    struct rx_connection *conn;
    struct rx_call *call;
    struct rx_peer *peer;
    int err = 0;
    int nCalls = 1, nBytes = 1;
    int bufferSize = 4000000;
    char *buffer;
    char *sendFile = 0;
    int setFD = 0;
    int jumbo = 0;

#if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
    setlinebuf(stdout);
    rxi_syscallp = test_syscall;
#endif


    argv++;
    argc--;
    while (argc && **argv == '-') {
	if (strcmp(*argv, "-silent") == 0)
	    print = 0;
	if (strcmp(*argv, "-jumbo") == 0)
	    jumbo = 1;
	else if (strcmp(*argv, "-nc") == 0)
	    nCalls = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-nb") == 0)
	    nBytes = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-np") == 0)
	    rx_nPackets = atoi(*++argv), argc--;
	else if (!strcmp(*argv, "-nsf"))
	    rxi_nSendFrags = atoi(*++argv), argc--;
	else if (!strcmp(*argv, "-nrf"))
	    rxi_nRecvFrags = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-twind") == 0)
	    rx_initSendWindow = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-rwind") == 0)
	    rx_initReceiveWindow = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-rxlog") == 0)
	    rxlog = 1;
	else if (strcmp(*argv, "-logstdout") == 0)
	    logstdout = 1;
	else if (strcmp(*argv, "-eventlog") == 0)
	    eventlog = 1;
	else if (strcmp(*argv, "-drop") == 0) {
#ifdef RXDEBUG
	    rx_intentionallyDroppedPacketsPer100 = atoi(*++argv), argc--;
#else
            fprintf(stderr, "ERROR: Compiled without RXDEBUG\n");
#endif
        }
	else if (strcmp(*argv, "-burst") == 0) {
	    burst = atoi(*++argv), argc--;
	    burstTime.sec = atoi(*++argv), argc--;
	    burstTime.usec = atoi(*++argv), argc--;
	} else if (strcmp(*argv, "-retry") == 0) {
	    retryTime.sec = atoi(*++argv), argc--;
	    retryTime.usec = atoi(*++argv), argc--;
	} else if (strcmp(*argv, "-timeout") == 0)
	    timeout = atoi(*++argv), argc--;
	else if (strcmp(*argv, "-fill") == 0)
	    fillPackets++;
	else if (strcmp(*argv, "-file") == 0)
	    sendFile = *++argv, argc--;
	else if (strcmp(*argv, "-timereadvs") == 0)
	    timeReadvs = 1;
	else if (strcmp(*argv, "-wait") == 0) {
	    /* Wait time between calls--to test lastack code */
	    waitTime.sec = atoi(*++argv), argc--;
	    waitTime.usec = atoi(*++argv), argc--;
	} else if (strcmp(*argv, "-compute") == 0) {
	    /* Simulated "compute" time for each call--to test acknowledgement protocol.  This is simulated by doing an iomgr_select:  imperfect, admittedly. */
	    computeTime.sec = atoi(*++argv), argc--;
	    computeTime.usec = atoi(*++argv), argc--;
	} else if (strcmp(*argv, "-fd") == 0) {
	    /* Open at least this many fd's. */
	    setFD = atoi(*++argv), argc--;
	} else {
	    err = 1;
	    break;
	}
	argv++, argc--;
    }
    if (err || argc != 1)
	Quit("usage: rx_ctest [-silent] [-rxlog] [-eventlog] [-nc NCALLS] [-np NPACKETS] hostname");
    hostname = *argv++, argc--;

    if (rxlog || eventlog) {
	if (logstdout)
	    debugFile = stdout;
	else
	    debugFile = fopen("rx_ctest.db", "w");
	if (debugFile == NULL)
	    Quit("Couldn't open rx_ctest.db");
	if (rxlog)
	    rx_debugFile = debugFile;
	if (eventlog)
	    rxevent_debugFile = debugFile;
    }

    signal(SIGINT, intSignal);	/*Changed to sigquit since dbx is broken right now */
#ifndef AFS_NT40_ENV
    signal(SIGQUIT, quitSignal);
#endif

#ifdef AFS_NT40_ENV
    if (afs_winsockInit() < 0) {
	printf("Can't initialize winsock.\n");
	exit(1);
    }
    rx_EnableHotThread();
#endif

    rx_SetUdpBufSize(256 * 1024);

    if (!jumbo)
        rx_SetNoJumbo();

    hostent = gethostbyname(hostname);
    if (!hostent)
	Abort("host %s not found", hostname);
    if (hostent->h_length != 4)
	Abort("host address is disagreeable length (%d)", hostent->h_length);
    memcpy((char *)&host, hostent->h_addr, sizeof(host));
    if (setFD > 0)
	OpenFD(setFD);
    if (rx_Init(0) != 0) {
	printf("RX failed to initialize, exiting.\n");
	exit(2);
    }
    if (setFD > 0) {
	printf("rx_socket=%d\n", rx_socket);
    }

    printf("Using %d packet buffers\n", rx_nPackets);

    conn =
	rx_NewConnection(host, htons(2500), 3,
			 rxnull_NewClientSecurityObject(), 0);

    if (!conn)
	Abort("unable to make a new connection");

    /* Set initial parameters.  This is (currently) not the approved interface */
    peer = rx_PeerOf(conn);
    if (burst)
	peer->burstSize = peer->burst = burst;
    if (!clock_IsZero(&burstTime))
	peer->burstWait = burstTime;
    if (!clock_IsZero(&retryTime))
	peer->rtt = _8THMSEC(&retryTime);
    if (sendFile)
	SendFile(sendFile, conn);
    else {
	buffer = (char *)osi_Alloc(bufferSize);
	while (nCalls--) {
	    struct clock startTime;
	    struct timeval t;
	    int nbytes;
	    int nSent;
	    int bytesSent = 0;
	    int bytesRead = 0;
	    call = rx_NewCall(conn);
	    if (!call)
		Abort("unable to make a new call");

	    clock_GetTime(&startTime);
	    for (bytesSent = 0; bytesSent < nBytes; bytesSent += nSent) {
		int tryCount;
		tryCount =
		    (bufferSize >
		     nBytes - bytesSent) ? nBytes - bytesSent : bufferSize;
		nSent = rx_Write(call, buffer, tryCount);
		if (nSent == 0)
		    break;

	    }
	    for (bytesRead = 0; (nbytes = rx_Read(call, buffer, bufferSize));
		 bytesRead += nbytes) {
	    };
	    if (print)
		printf("Received %d characters in response\n", bytesRead);
	    err = rx_EndCall(call, 0);
	    if (err)
		printf("Error %d returned from rpc call\n", err);
	    else {
		struct clock totalTime;
		float elapsedTime;
		clock_GetTime(&totalTime);
		clock_Sub(&totalTime, &startTime);
		elapsedTime = clock_Float(&totalTime);
		fprintf(stderr,
			"Sent %d bytes in %0.3f seconds:  %0.0f bytes per second\n",
			bytesSent, elapsedTime, bytesSent / elapsedTime);
	    }
	    if (!clock_IsZero(&computeTime)) {
		t.tv_sec = computeTime.sec;
		t.tv_usec = computeTime.usec;
		if (select(0, 0, 0, 0, &t) != 0)
		    Quit("Select didn't return 0");
	    }
	    if (!clock_IsZero(&waitTime)) {
		struct timeval t;
		t.tv_sec = waitTime.sec;
		t.tv_usec = waitTime.usec;
#ifdef AFS_PTHREAD_ENV
		select(0, 0, 0, 0, &t);
#else
		IOMGR_Sleep(t.tv_sec);
#endif
	    }
            if (debugFile)
                rx_PrintPeerStats(debugFile, rx_PeerOf(conn));
            rx_PrintPeerStats(stdout, rx_PeerOf(conn));
	}
    }
    Quit("testclient: done!\n");
    return 0;
}
Exemple #2
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;
}