当前位置: 首页 > 工具软件 > Dynamo > 使用案例 >

Dynamo命令行管理器

解阳泽
2023-12-01
#include "IOMessage.h"
#include "IOPortTCP.h"
#include "IOPort.h"

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define IDLE (0)
#define WAITCONNECT (1)
#define CONNECTED (2)

class Dynamo
{
    #define TESTTING (0x01)
    #define UNTEST   (0x00)
public:
    Dynamo()
    {
        status = IDLE;
        targets = new struct Target_Spec[MAX_TARGETS];
        targetsIdArray = new int[MAX_TARGETS];
        specs = new Test_Spec[MAX_ACCESS_SPECS];
    }
    ~Dynamo()
    {
        delete []targets;
        delete []targetsIdArray;
        delete []specs;
    }
    bool Login();
    bool Exit(int workerid);

    char addr[512];
    unsigned short portNumber;
    
    int getstatus()
    {
        return status;
    };
    void setstatus(int status)
    {
        this->status = status;
    }

    void reportTargest();
    void setTargets(int workerId);
    void addTargetId(int id, int queueDepth, int transPerConn);
    void addWorker(int count);
    void prepareDisks(int workerId);
    void setSpecs(int workerId, struct Test_Spec *spec, int count);
    bool startTests(int workerId = ALL_WORKERS);
private:
    int  status;
    PortTCP dynamo;
    Message smsg,rmsg;
    Data_Message sdatamsg, rdatamsg;
    struct Target_Spec *targets;
    int targetsCount;
    int *targetsIdArray;
    int targetIdx;
    struct Test_Spec *specs;
    
};

bool Dynamo::startTests(int workerId)
{
    smsg.purpose = START;
    smsg.data = workerId;
    dynamo.Send((LPVOID)&smsg);
    memset(&rmsg, 0, MESSAGE_SIZE);
    dynamo.Receive((LPVOID)&rmsg);
    if (rmsg.data)
    {
        printf("start test on workerid (%d) success.\n", workerId);
        return true;
    }
    return false;
}

void Dynamo::prepareDisks(int workerId)
{
    smsg.purpose = PREP_DISKS;
    smsg.data = workerId;
    dynamo.Send((LPVOID)&smsg);
    dynamo.Receive((LPVOID)&rmsg, MESSAGE_SIZE);
    
    return;
}

void Dynamo::setSpecs(int workerId, struct Test_Spec *spec, int count)
{
    memcpy(specs, spec, count*sizeof(struct Test_Spec));
    smsg.purpose = SET_ACCESS;
    smsg.data = workerId;
    dynamo.Send((LPVOID)&smsg);
    sdatamsg.count = count;
    memcpy(&sdatamsg.data.spec, spec,  count*sizeof(struct Test_Spec));
    dynamo.Send((LPVOID)&sdatamsg, DATA_MESSAGE_SIZE);
    dynamo.Receive((LPVOID)&rmsg);
}

void Dynamo::addTargetId(int id, int queueDepth, int transPerConn)
{
    if (id > MAX_TARGETS)
    {
        printf("target id out of range(%d),max(%d)\n", id, MAX_TARGETS);
        return;
    }

    targetsIdArray[targetIdx++] = id;
    targets[id].queue_depth = queueDepth;
    targets[id].test_connection_rate = false;
    targets[id].trans_per_conn = transPerConn;
}

void Dynamo::addWorker(int count)
{
    smsg.purpose = ADD_WORKERS;
    smsg.data = count;
    printf("worker count %d\n", count);
    if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return;
    }
    if(dynamo.Receive((LPVOID)&rmsg) != MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return;
    }
}

void Dynamo::setTargets(int workerId)
{
    int targetToTestCnt = targetIdx;
    int i;
    
    smsg.purpose = SET_TARGETS;
    smsg.data = workerId;
    if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return;
    }
    sdatamsg.count = targetToTestCnt;
    printf("target count = %d\n", targetToTestCnt);
    for (int i = 0; i < targetToTestCnt; i++)
    {   printf("setting taget %d, name %s\n", targetsIdArray[i], targets[targetsIdArray[i]].name); 
        memcpy(&sdatamsg.data.targets[i], &targets[targetsIdArray[i]], sizeof(struct Target_Spec));
    }
    if (dynamo.Send((LPVOID)&sdatamsg, DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return;
    }
    if (dynamo.Receive((LPVOID)&rdatamsg, DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return;
    }
}

void Dynamo::reportTargest()
{
    smsg.purpose = REPORT_TARGETS;
    if (dynamo.Send((LPVOID)&smsg) != MESSAGE_SIZE)
    {
        printf("%d:send message size fail\n", __LINE__);
        return ;
    }
    if (dynamo.Receive((LPVOID)&rdatamsg,DATA_MESSAGE_SIZE) != DATA_MESSAGE_SIZE)
    {
        printf("%d:recv message size fail\n", __LINE__);
        return;
    }
    targetsCount = rdatamsg.count;

    memcpy(targets, rdatamsg.data.targets, targetsCount*sizeof(struct Target_Spec));
    for (int i = 0; i < targetsCount; i++)
    {
        printf("ID:[%d],target name(%s), type(%x)\n", 
            i, rdatamsg.data.targets[i].name, rdatamsg.data.targets[i].type);
    }
    return;
}


bool Dynamo::Login()
{
    if (status != WAITCONNECT)
    {
        return false;
    }

    if (dynamo.Connect(addr,portNumber))
    {
        status= CONNECTED;
        return true;
    }

    return false;
}

bool Dynamo::Exit(int workerid)
{
    smsg.purpose= EXIT;
    smsg.data = workerid;
    if (dynamo.Send((LPVOID)&smsg))
    {   
        status= IDLE;
        return true;
    }
    return false;
}


class DynamoManager
{
    #define MAX_DYNAMOS (5)
public:
    DynamoManager()
    {
        listenDyanmo = new PortTCP();
        listenDyanmo->Create(NULL, NULL, MESSAGE_PORT_SIZE, WELL_KNOWN_TCP_PORT);
        dynamos = new Dynamo[MAX_DYNAMOS];
        status = IDLE;
    }

    void Start()
    {
        
        //pthread_create(&newThread, NULL, (void *(*)(void *))AccecptWapper, (void *)this);
	    //pthread_detach(newThread);
    }

    int startTestToDynamo(int dynamoId, int workerId = ALL_WORKERS);


    pthread_t getThread()
    {
        return newThread;
    }

    void setAccessToDynamo(int dynamoId, int workerid, struct Test_Spec * spec,int count);
    void setTestTargetToDynamo(int dynamoId,int workerid, int targetId, int queueDepth, int transPerConn);
    int LoginAllDynamos()
    {
        int i;
        int connectedNum = 0;
        for (i = 0; i < MAX_DYNAMOS; i++)
        {
            printf("dynamo(%d):status(%d)\n", i, dynamos[i].getstatus());
            if (dynamos[i].Login())
                connectedNum++;
        }
        return connectedNum;
    }

    void ExitDynamobyId(int id, int workerCount)
    {
        dynamos[id].Exit(workerCount);
    }

    void reportTargetbyId(int id)
    {
        printf("=====================\n");
        dynamos[id].reportTargest();
        printf("=====================\n");
    }

    void prepDiskToDynamo(int dynamoId, int workerId);
    ~DynamoManager()
    {
        delete listenDyanmo;
        delete []dynamos;
    }

    Dynamo* GetOneDynamo(int id)
    {
        return &dynamos[id];
    }

    int getStaus()
    {
        return status;
    }

    void addWorkerToDynamo(int dynamoId, int count);
    bool Accept()
    {
        if (!listenDyanmo->Accept())
        {
            
        }

        listenDyanmo->Receive((LPVOID)&msg);
        
        if (msg.purpose != LOGIN)
        {
            printf("bad message\n");
            return false;
        } 

        listenDyanmo->Receive((LPVOID)&data_msg, DATA_MESSAGE_SIZE);
        msg.data = LOGIN_OK;
        listenDyanmo->Send((LPVOID)&msg);
        
        int i;
        for (i = 0; i < MAX_DYNAMOS; i++)
        {
            if (dynamos[i].getstatus() == IDLE)
            {
                strncpy((char *)&dynamos[i].addr, "127.0.0.1", 512);
                dynamos[i].portNumber = data_msg.data.manager_info.port_number;
                dynamos[i].setstatus(WAITCONNECT);
                printf("dynamoid(%d), name(%s), port_number(%u), processors(%d), speed(%f), version(%s)\n", 
                    i,data_msg.data.manager_info.names[0], data_msg.data.manager_info.port_number,
                    data_msg.data.manager_info.processors,data_msg.data.manager_info.processor_speed,
                    data_msg.data.manager_info.version);
                break;
            }
        }

        if (MAX_DYNAMOS == i)
        {
            //send max login message
        }

        return true;
        
    }
    
protected:
        PortTCP *listenDyanmo;
        Dynamo *dynamos;
        int status;
        Message msg;
        Data_Message data_msg;
        pthread_t newThread;
};

void DynamoManager::setTestTargetToDynamo(int dynamoId,int workerid, int targetId, int queueDepth, int transPerConn)
{
    
    dynamos[dynamoId].addTargetId(targetId, queueDepth, transPerConn);
    dynamos[dynamoId].setTargets(workerid);
}

int DynamoManager::startTestToDynamo(int dynamoId,int workerId)
{
    dynamos[dynamoId].startTests(workerId);
}

void DynamoManager::setAccessToDynamo(int dynamoId, int workerid, struct Test_Spec * spec,int count)
{
    dynamos[dynamoId].setSpecs(workerid,spec,count);
}

void DynamoManager::addWorkerToDynamo(int dynamoId, int count)
{
    if (dynamoId > MAX_DYNAMOS)
    {
        printf("out max dynamos\n");
    }
    dynamos[dynamoId].addWorker(count);
}

void DynamoManager::prepDiskToDynamo(int dynamoId, int workerId)
{
    dynamos[dynamoId].prepareDisks(workerId);
}

void AccecptWapper(void *dynamoManager)
{
    DynamoManager *dm = (DynamoManager *)dynamoManager;

    while(dm->getStaus() != IDLE)
    {
        if (dm->Accept())
        {
            return;
        }
    }
    
}

int main(int argc, char *argv)
{
	DynamoManager dm;
    int i = 0;
    struct Test_Spec spec;
    Access_Spec  *tmpAcc = spec.access;

    strncpy((char *)spec.name, "tata", MAX_WORKER_NAME);
    spec.default_assignment = 0;
    tmpAcc[0].align = 0;
    tmpAcc[0].burst = 0;
    tmpAcc[0].delay = 0;
    tmpAcc[0].of_size = 100;
    tmpAcc[0].random = 0;
    tmpAcc[0].reads = 100;
    tmpAcc[0].reply = 0;
    tmpAcc[0].size = 512;
    //for (; i < 2; i++)
    //{
        dm.Accept();
    //}
    
    printf("conneced %d dynamoes\n",dm.LoginAllDynamos());
    
    dm.reportTargetbyId(0);
    dm.addWorkerToDynamo(0, 1);
    //dm.addWorkerToDynamo(0, 2);
    dm.setTestTargetToDynamo(0, 0, 4,1,1);
    //dm.prepDiskToDynamo(0, 0);
    dm.setAccessToDynamo(0,0,&spec,1);
    dm.startTestToDynamo(0,0);
    

    while(1)
    {
        sleep(1);
        printf("idle...\n");
    }

    dm.ExitDynamobyId(0, 1);
   
    return 0;
}


=====================================================================

makefile

###############################################################################
##                                                                           ##
##  Dynamo / Makefile-Linux.i386                                             ##
##                                                                           ##
## ------------------------------------------------------------------------- ##
##                                                                           ##
##  Job .......: The Makefile for the GNU/Linux on i386 variant.             ##
##                                                                           ##
## ------------------------------------------------------------------------- ##
##                                                                           ##
##  Intel Open Source License                                                ##
##                                                                           ##
##  Copyright (c) 2001 Intel Corporation                                     ##
##  All rights reserved.                                                     ##
##  Redistribution and use in source and binary forms, with or without       ##
##  modification, are permitted provided that the following conditions       ##
##  are met:                                                                 ##
##                                                                           ##
##  Redistributions of source code must retain the above copyright notice,   ##
##  this list of conditions and the following disclaimer.                    ##
##                                                                           ##
##  Redistributions in binary form must reproduce the above copyright        ##
##  notice, this list of conditions and the following disclaimer in the      ##
##  documentation and/or other materials provided with the distribution.     ##
##                                                                           ##
##  Neither the name of the Intel Corporation nor the names of its           ##
##  contributors may be used to endorse or promote products derived from     ##
##  this software without specific prior written permission.                 ##
##                                                                           ##
##  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      ##
##  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      ##
##  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    ##
##  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR      ##
##  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,         ##
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT         ##
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    ##
##  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    ##
##  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT      ##
##  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    ##
##  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     ##
##                                                                           ##
## ------------------------------------------------------------------------- ##
##                                                                           ##
##  Remarks ...: <none>                                                      ##
##                                                                           ##
## ------------------------------------------------------------------------- ##
##                                                                           ##
##  Changes ...: 2005-02-26 (mingz@ele.uri.edu)                              ##
##               - Added NOMINMAX definition.                                ##
##               2004-08-21 (daniel.scheibli@edelbyte.org)                   ##
##               - Removed old global defines that are no longer used /      ##
##                 named different, like IOMTR_SETTING_OVERRIDE_FS           ##
##               - Removed IOPerformance.o from the list of objects to       ##
##                 be linked, as for Linux only IOPerformanceLinux.o is      ##
##                 relevant.                                                 ##
##               2004-08-07 (daniel.scheibli@edelbyte.org)                   ##
##               - Added iometer target and explained that there is no       ##
##                 Iometer GUI for non MS Windows platforms so far.          ##
##               2004-03-28 (daniel.scheibli@edelbyte.org)                   ##
##               - Removed the IOManagerSolaris.o module from the list of    ##
##                 Objects (OBJECTS) - as suggested by Ming Zhang.           ##
##               2003-12-21 (daniel.scheibli@edelbyte.org)                   ##
##               - Changed DYNAMO_DESTRUCTIVE to IOMTR_SETTING_OVERRIDE_FS   ##
##               - Changed NO_DYNAMO_VI to IOMTR_SETTING_VI_SUPPORT          ##
##               2003-07-27 (daniel.scheibli@edelbyte.org)                   ##
##               - Removed the [BIG|LITTLE]_ENDIAN_ARCH defines, because     ##
##                 they have been replaced by IsBigEndian() function calls.  ##
##               2003-07-13 (daniel.scheibli@edelbyte.org)                   ##
##               - Minor cleanup of this file.                               ##
##               - Implemented the IOMTR_[OSFAMILY|OS|CPU]_* global define   ##
##                 as well as their integrity checks.                        ##
##               - Integrated the License Statement into this header.        ##
##               2003-03-05 (daniel.scheibli@edelbyte.org)                   ##
##               - Removed LINUX_DEBUG, because it is redundant.             ##
##                 We can use the generic _DEBUG therefor.                   ##
##               2003-03-04 (joe@eiler.net)                                  ##
##               - Changed NO_LINUX_VI to be NO_DYNAMO_VI                    ##
##               - Merged rdtsc.c into IOTime.cpp                            ##
##               - Some minor cleanup                                        ##
##               2003-02-09 (daniel.scheibli@edelbyte.org)                   ##
##               - Added the default variable CXX again.                     ##
##               2003-02-02 (daniel.scheibli@edelbyte.org)                   ##
##               - Added new header holding the changelog.                   ##
##               - Applied the iometer-initial-largefile.patch file          ##
##                 (brings some global defines).                             ##
##               - Removed the "depend" target related stuff.                ##
##               - Added the typical "all" target.                           ##
##               - Removed AS, CC and changed STRIP variable.                ##
##               - Swapped the librt.a patch stuff, because it is more       ##
##                 common, that someone runs a glibc version 2.2 or later    ##
##                 then running an old one.                                  ##
##               - Sort of the object file list (OBJECTS variable).          ##
##                                                                           ##
###############################################################################
.MAKE_VERSION: VERSION-1.0

# un-comment out .IGNORE to suppress error messages and not stop make on errors.
#.IGNORE:
.SUFFIXES: .cpp .c .o

RM=/bin/rm -f
MV=/bin/mv
TOUCH=/usr/bin/touch
STRIP=/usr/bin/strip


# Some common definitions used.
# Note 1) -DWORKAROUND_MOD_BUG can be dropped if -O is used in place of -g in CFLAGS
# Note 2) -D_DETAILS=1 -D_DEBUG enables maximum debug information
#CFLAGS=	-O3 
#CFLAGS=-Wall 
CFLAGS= -Wall \
	-D_GNU_SOURCE \
	-DIOMTR_OSFAMILY_UNIX -DIOMTR_OS_LINUX \
	-DIOMTR_CPU_I386 \
	-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \
	-D_REENTRANT -DNOMINMAX \
	-ggdb


# For older versions of the librt.a it is needed to apply a patch (see the
# file "Documentation/LinuxReadme.txt" for an explanation of the patch,
# and "Documentation/linux-rt-2.1.2.patch" for the patch itself).
# If you have glibc version less then 2.2, the patch is needed; in this
# case, change this line as follows:
#
# LDFLAGS= ../glibc-2.1/rt/librt.a -lpthread
LDFLAGS= -lrt -lpthread

OBJECTS= IOGlobals.o \
         Pulsar.o \
         IOManager.o IOManagerLinux.o \
	 IOGrunt.o \
	 IOTarget.o IOTargetDisk.o IOTargetTCP.o \
	 IOPort.o IOPortTCP.o \
	 Network.o NetTCP.o \
	 ByteOrder.o \
	 IOPerformanceLinux.o \
	 IOTime.o \
	 IOCQAIO.o IOCompletionQ.o \
	 IOAccess.o
IOMANAGEROBJS=IOPort.o \
	IOPortTCP.o \
	IOCommand.o \
	IOCompletionQ.o
	
		

# Make Rules
help:
	@echo
	@echo "Please pick one of the listed targets:"
	@echo                                                              
	@echo "   all       Build the binaries"
	@echo "   dynamo    Build the dynamo binary"
	@echo "   iometer   Build the iometer binary (not supported) *"
	@echo "   clean     Remove old binaries and object files"
	@echo                                                              
	@echo "   * = The Iometer GUI is so far only available for MS Windows," 
	@echo "       but you can use it to control dynamo's running on Linux." 
	@echo                                                              

all: dynamo, iocommand

dynamo: $(OBJECTS)
	$(CXX) $(CFLAGS) -o dynamo $(OBJECTS) $(LIBS) $(LDFLAGS)

iocommand: $(IOMANAGEROBJS)
	$(CXX) $(CFLAGS) -o iocommand $(IOMANAGEROBJS) $(LIBS) $(LDFLAGS)
	
clean:
	$(RM) $(OBJECTS) dynamo

install:
	echo "Not Supported."

iometer:
	echo "Not Supported."

.cpp.o:
	$(CXX) $(CFLAGS) -c $<

.c.o:
	$(CXX) $(CFLAGS) -c $<


 

 类似资料: