From: mquinson Date: Tue, 2 Nov 2004 11:44:30 +0000 (+0000) Subject: some more work on the bandwidth test module (ie, root of ALNeM) modernization. Still... X-Git-Tag: v3.3~4895 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/a4488cf61cb9b235eb6a370dbd0ab63ff936e72a some more work on the bandwidth test module (ie, root of ALNeM) modernization. Still lot to do git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@455 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/src/amok/Bandwidth/bandwidth.c b/src/amok/Bandwidth/bandwidth.c new file mode 100644 index 0000000000..ab3202d9c0 --- /dev/null +++ b/src/amok/Bandwidth/bandwidth.c @@ -0,0 +1,685 @@ +/* $Id$ */ + +/* amok_bandwidth - Bandwidth tests facilities */ + +/* Authors: Martin Quinson */ +/* Copyright (C) 2003, 2004 the OURAGAN project. */ + +/* This program is free software; you can redistribute it and/or modify it + under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "amok/Bandwidth/bandwidth_private.h" +#include "gras/messages.h" + +GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(bw,amok,"Bandwidth testing"); + +static short _amok_bw_initialized = 0; + +/**** code ****/ +void amok_bw_init(void) { + gras_error_t errcode; + gras_datadesc_type_t bw_request_desc, bw_res_desc, sat_request_desc; + + if (_amok_bw_initialized) + return; + + amok_base_init(); + + /* Build the datatype descriptions */ + bw_request_desc = gras_datadesc_struct("s_bw_request_t"); + gras_datadesc_struct_append(bw_request_desc,"host",gras_datadesc_by_name("gras_host_t")); + gras_datadesc_struct_append(bw_request_desc,"buf_size",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_append(bw_request_desc,"exp_size",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_append(bw_request_desc,"msg_size",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_close(bw_request_desc); + bw_request_desc = gras_datadesc_ref("bw_request_t",bw_request_desc); + + bw_res_desc = gras_datadesc_struct("s_bw_res_t"); + gras_datadesc_struct_append(bw_res_desc,"err",gras_datadesc_by_name("s_amok_remoterr_t")); + gras_datadesc_struct_append(bw_res_desc,"timestamp",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_append(bw_res_desc,"seconds",gras_datadesc_by_name("double")); + gras_datadesc_struct_append(bw_res_desc,"bw",gras_datadesc_by_name("double")); + gras_datadesc_struct_close(bw_res_desc); + bw_res_desc = gras_datadesc_ref("bw_res_t",bw_res_desc); + + sat_request_desc = gras_datadesc_struct("s_sat_request_desc_t"); + gras_datadesc_struct_append(sat_request_desc,"host",gras_datadesc_by_name("gras_host_t")); + gras_datadesc_struct_append(sat_request_desc,"msg_size",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_append(sat_request_desc,"timeout",gras_datadesc_by_name("unsigned int")); + gras_datadesc_struct_close(sat_request_desc); + sat_request_desc = gras_datadesc_ref("sat_request_t",sat_request_desc); + + /* Register the bandwidth messages */ + gras_msgtype_declare("BW request", bw_request_desc); + gras_msgtype_declare("BW result", bw_res_desc); + gras_msgtype_declare("BW handshake", bw_request_desc); + gras_msgtype_declare("BW handshake ACK", bw_request_desc); + + /* Register the saturation messages */ + gras_msgtype_declare("SAT start", sat_request_desc); + gras_msgtype_declare("SAT started", gras_datadesc_by_name("amok_remoterr_t")); + gras_msgtype_declare("SAT begin", sat_request_desc); + gras_msgtype_declare("SAT begun", gras_datadesc_by_name("amok_remoterr_t")); + gras_msgtype_declare("SAT end", NULL); + gras_msgtype_declare("SAT ended", gras_datadesc_by_name("amok_remoterr_t")); + gras_msgtype_declare("SAT stop", NULL); + gras_msgtype_declare("SAT stopped", gras_datadesc_by_name("amok_remoterr_t")); + + /* Register the callbacks */ + gras_cb_register(gras_msgtype_by_name("BW request"), + &amok_bw_cb_bw_request); + gras_cb_register(gras_msgtype_by_name("BW handshake"), + &amok_bw_cb_bw_handshake); + + gras_cb_register(gras_msgtype_by_name("SAT start"), + &amok_bw_cb_sat_start); + gras_cb_register(gras_msgtype_by_name("SAT begin"), + &amok_bw_cb_sat_begin); + + _amok_bw_initialized =1; +} + +void amok_bw_exit(void) { + if (! _amok_bw_initialized) + return; + + gras_cb_unregister(gras_msgtype_by_name("BW request"), + &amok_bw_cb_bw_request); + gras_cb_unregister(gras_msgtype_by_name("BW handshake"), + &amok_bw_cb_bw_handshake); + + gras_cb_unregister(gras_msgtype_by_name("SAT start"), + &amok_bw_cb_sat_start); + gras_cb_unregister(gras_msgtype_by_name("SAT begin"), + &amok_bw_cb_sat_begin); + + _amok_bw_initialized = 0; +} + + + +/* *************************************************************************** + * Bandwidth tests + * ***************************************************************************/ + +/** + * amok_bw_test: + * + * Conduct a test between the local host and @peer, and + * report the result in last args + */ +gras_error_t amok_bw_test(gras_socket_t peer, + unsigned int buf_size,unsigned int exp_size,unsigned int msg_size, + /*OUT*/ double *sec, double *bw) { + gras_socket_t rawIn,rawOut; /* raw sockets for the experiments */ + gras_socket_t sock_dummy; /* ignored arg to msg_wait */ + int port; + gras_error_t errcode; + bw_request_t request,request_ack; + + for (port = 5000, errcode = system_error; + errcode == system_error; + errcode = gras_socket_server_ext(++port,buf_size,1,&rawIn)); + if (errcode != no_error) { + ERROR1("Error %s encountered while opening a raw socket", + gras_error_name(errcode)); + return errcode; + } + + request=gras_new0(s_bw_request_t,1); + request->buf_size=buf_size; + request->exp_size=exp_size; + request->msg_size=msg_size; + request->host.name = NULL; + request->host.port = gras_socket_my_port(rawIn); + INFO1("Send an handshake to get the dude connect to port %d on me", request->host.port); + + if ((errcode=gras_msg_send(peer,gras_msgtype_by_name("BW handshake"),&request))) { + ERROR1("Error %s encountered while sending the BW request.", gras_error_name(errcode)); + return errcode; + } + if ((errcode=gras_msg_wait(60,gras_msgtype_by_name("BW handshake ACK"),&sock_dummy,&request_ack))) { + ERROR1("Error %s encountered while waiting for the answer to BW request.\n", + gras_error_name(errcode)); + return errcode; + } + + /* FIXME: What if there is a remote error? */ + + if((errcode=gras_socket_client_ext(gras_socket_peer_name(peer),request_ack->host.port, buf_size,1,&rawOut))) { + ERROR3("Error %s encountered while opening the raw socket to %s:%d for BW test\n", + gras_error_name(errcode),gras_socket_peer_name(peer),request_ack->host.port); + return errcode; + } + gras_free(request_ack); + INFO0("Got ACK"); + + *sec=gras_os_time(); + if ((errcode=gras_socket_raw_send(rawOut,120,exp_size,msg_size)) || + (errcode=gras_socket_raw_recv(rawIn,120,1,1))) { + ERROR1("Error %s encountered while sending the BW experiment.", + gras_error_name(errcode)); + gras_socket_close(rawOut); + gras_socket_close(rawIn); + return errcode; + } + *sec = gras_os_time() - *sec; + *bw = ((double)exp_size /* 8.0*/) / *sec / (1024.0 *1024.0); +INFO0("DOOONE"); + + gras_socket_close(rawIn); + gras_socket_close(rawOut); + return no_error; +} + + +/* Callback to the "BW handshake" message: + opens a server raw socket, + indicate its port in an "BW handshaked" message, + receive the corresponding data on the raw socket, + close the raw socket +*/ +int amok_bw_cb_bw_handshake(gras_socket_t expeditor, + void *payload) { + gras_socket_t rawIn,rawOut; + bw_request_t request=*(bw_request_t*)payload; + bw_request_t answer; + gras_error_t errcode; + int port; + + INFO2("Got an handshake to connect to %s:%d", + request->host.name,request->host.port); + + answer = gras_new0(s_bw_request_t,1); + + for (port = 5000, errcode = system_error; + errcode == system_error; + errcode = gras_socket_server_ext(++port,request->buf_size,1,&rawIn)); + if (errcode != no_error) { + ERROR1("Error %s encountered while opening a raw socket", gras_error_name(errcode)); + /* FIXME: tell error to remote */ + return 1; + } + + if ((errcode=gras_socket_client_ext(gras_socket_peer_name(expeditor),request->host.port, + request->buf_size,1,&rawOut))) { + ERROR3("Error '%s' encountered while opening a raw socket to %s:%d", + gras_error_name(errcode),gras_socket_peer_name(expeditor),request->host.port); + /* FIXME: tell error to remote */ + return 1; + } + + answer->buf_size=request->buf_size; + answer->exp_size=request->exp_size; + answer->msg_size=request->msg_size; + answer->host.port=gras_socket_my_port(rawIn); + + if ((errcode=gras_msg_send(expeditor,gras_msgtype_by_name("BW handshake ACK"),&answer))) { + ERROR1("Error %s encountered while sending the answer.", + gras_error_name(errcode)); + gras_socket_close(rawIn); + gras_socket_close(rawOut); + /* FIXME: tell error to remote */ + return 1; + } + INFO4("BW handshake answered. buf_size=%d exp_size=%d msg_size=%d port=%d", + answer->buf_size,answer->exp_size,answer->msg_size,answer->host.port); + + if ((errcode=gras_socket_raw_recv(rawIn, 120,request->exp_size,request->msg_size)) || + (errcode=gras_socket_raw_send(rawOut,120,1,1))) { + ERROR1("Error %s encountered while receiving the experiment.", + gras_error_name(errcode)); + gras_socket_close(rawIn); + gras_socket_close(rawOut); + /* FIXME: tell error to remote ? */ + return 1; + } + gras_socket_close(rawIn); + gras_socket_close(rawOut); + return 1; +} + +int amok_bw_cb_bw_request(gras_socket_t expeditor, + void *payload) {return 1;} + +int amok_bw_cb_sat_start(gras_socket_t expeditor, + void *payload) {return 1;} +int amok_bw_cb_sat_begin(gras_socket_t expeditor, + void *payload) {return 1;} + +#if 0 +/* function to request a BW test between two external hosts */ +gras_error_t grasbw_request(const char* from_name,unsigned int from_port, + const char* to_name,unsigned int to_port, + unsigned int bufSize,unsigned int expSize,unsigned int msgSize, + /*OUT*/ double *sec, double*bw) { + + gras_sock_t *sock; + gras_msg_t *answer; + gras_error_t errcode; + /* The request */ + BwExp_t *request; + msgHost_t *target; + + if((errcode=gras_sock_client_open(from_name,from_port,&sock))) { + fprintf(stderr,"grasbw_request(): Error %s encountered while contacting the actuator\n", + gras_error_name(errcode)); + return errcode; + } + if (!(request=(BwExp_t *)malloc(sizeof(BwExp_t))) || + !(target=(msgHost_t*)malloc(sizeof(msgHost_t)))) { + fprintf(stderr,"grasbw_test(): Malloc error\n"); + gras_sock_close(sock); + return malloc_error; + } + + request->bufSize=bufSize; + request->expSize=expSize; + request->msgSize=msgSize; + strcpy(target->host,to_name); + target->port=to_port; + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_BW_REQUEST, 2, + target,1, + request,1))) { + fprintf(stderr,"grasbw_request(): Error %s encountered while sending the request.\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + if ((errcode=gras_msg_wait(240,GRASMSG_BW_RESULT,&answer))) { + fprintf(stderr,"grasbw_request(): Error %s encountered while waiting for the answer.\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"grasbw_request(): Peer reported error %s (%s).\n", + gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return errcode; + } + + /* fprintf(stderr,"sec=%p",gras_msg_ctn(answer,1,0,msgResult_t)); */ + *sec=gras_msg_ctn(answer,1,0,msgResult_t).value; + *bw=gras_msg_ctn(answer,1,1,msgResult_t).value; + + gras_msg_free(answer); + gras_sock_close(sock); + return no_error; +} + +int grasbw_cbBWRequest(gras_msg_t *msg) { + /* specification of the test to run */ + char* to_name=gras_msg_ctn(msg,0,0,msgHost_t).host; + unsigned int to_port=gras_msg_ctn(msg,0,0,msgHost_t).port; + + unsigned int bufSize=gras_msg_ctn(msg,1,0,BwExp_t).bufSize; + unsigned int expSize=gras_msg_ctn(msg,1,0,BwExp_t).expSize; + unsigned int msgSize=gras_msg_ctn(msg,1,0,BwExp_t).msgSize; + /* our answer */ + msgError_t *error; + msgResult_t *res; + + if (!(error=(msgError_t *)malloc(sizeof(msgError_t))) || + !(res=(msgResult_t *)malloc(sizeof(msgResult_t) * 2))) { + fprintf(stderr,"%s:%d:grasbw_cbRequest: Malloc error\n",__FILE__,__LINE__); + return malloc_error; + } + + if ((error->errcode=grasbw_test(to_name,to_port,bufSize,expSize,msgSize, + &(res[0].value),&(res[1].value) ))) { + fprintf(stderr, + "%s:%d:grasbw_cbRequest: Error %s encountered while doing the test\n", + __FILE__,__LINE__,gras_error_name(error->errcode)); + strncpy(error->errmsg,"Error within grasbw_test",ERRMSG_LEN); + gras_msg_new_and_send(msg->sock,GRASMSG_BW_RESULT,2, + error,1, + res,2); + return 1; + } + res[0].timestamp = (unsigned int) gras_time(); + res[1].timestamp = (unsigned int) gras_time(); + gras_msg_new_and_send(msg->sock,GRASMSG_BW_RESULT,2, + error,1, + res,2); + gras_msg_free(msg); + return 1; +} + +/* *************************************************************************** + * Link saturation + * ***************************************************************************/ + +gras_error_t grasbw_saturate_start(const char* from_name,unsigned int from_port, + const char* to_name,unsigned int to_port, + unsigned int msgSize, unsigned int timeout) { + gras_sock_t *sock; + gras_error_t errcode; + /* The request */ + SatExp_t *request; + msgHost_t *target; + /* answer */ + gras_msg_t *answer; + + if((errcode=gras_sock_client_open(from_name,from_port,&sock))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while contacting peer\n", + __FILE__,__LINE__,gras_error_name(errcode)); + return errcode; + } + if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t))) || + !(target=(msgHost_t*)malloc(sizeof(msgHost_t)))) { + fprintf(stderr,"%s:%d:saturate_start(): Malloc error\n",__FILE__,__LINE__); + gras_sock_close(sock); + return malloc_error; + } + + request->timeout=timeout; + request->msgSize=msgSize; + + strcpy(target->host,to_name); + target->port=to_port; + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_START, 2, + target,1, + request,1))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while sending the request.\n", + __FILE__,__LINE__,gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STARTED,&answer))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while waiting for the ACK.\n", + __FILE__,__LINE__,gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"%s:%d:saturate_start(): Peer reported error %s (%s).\n", + __FILE__,__LINE__,gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return errcode; + } + + gras_msg_free(answer); + gras_sock_close(sock); + return no_error; +} + +int grasbw_cbSatStart(gras_msg_t *msg) { + gras_rawsock_t *raw; + gras_sock_t *sock; + gras_error_t errcode; + double start; /* time to timeout */ + + /* specification of the test to run */ + char* to_name=gras_msg_ctn(msg,0,0,msgHost_t).host; + unsigned int to_port=gras_msg_ctn(msg,0,0,msgHost_t).port; + + unsigned int msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize; + unsigned int timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout; + unsigned int raw_port; + + /* The request */ + SatExp_t *request; + /* answer */ + gras_msg_t *answer; + + /* + fprintf(stderr,"grasbw_cbSatStart(sd=%p)\n",msg->sock); + fprintf(stderr,"(server=%d,raw=%d,fromPID=%d,toPID=%d,toHost=%p,toPort=%d,toChan=%d)\n", + msg->sock->server_sock,msg->sock->raw_sock,msg->sock->from_PID, + msg->sock->to_PID,msg->sock->to_host,msg->sock->to_port,msg->sock->to_chan); + */ + + /* Negociate the saturation with the peer */ + if((errcode=gras_sock_client_open(to_name,to_port,&sock))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while contacting peer\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot contact peer.\n"); + return 1; + } + if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t)))) { + fprintf(stderr,"cbSatStart(): Malloc error\n"); + gras_sock_close(sock); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + malloc_error,"Cannot build request.\n"); + return 1; + } + + request->timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout; + request->msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize; + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_BEGIN, 1, + request,1))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while sending the request.\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot send request.\n"); + gras_sock_close(sock); + return 1; + } + + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_BEGUN,&answer))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while waiting for the ACK.\n", + gras_error_name(errcode)); + gras_sock_close(sock); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode, + "Cannot receive the ACK.\n"); + return 1; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"cbSatStart(): Peer reported error %s (%s).\n", + gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode, + "Peer repported '%s'.\n",gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return 1; + } + + raw_port=gras_msg_ctn(answer,1,0,SatExp_t).port; + + if ((errcode=gras_rawsock_client_open(to_name,raw_port,msgSize,&raw))) { + fprintf(stderr,"cbSatStart(): Error %s while opening raw socket to %s:%d.\n", + gras_error_name(errcode),to_name,gras_msg_ctn(answer,1,0,SatExp_t).port); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot open raw socket.\n"); + gras_sock_close(sock); + return 1; + } + + /* send a train of data before repporting that XP is started */ + if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) { + fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot raw send.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + no_error,"Saturation started"); + gras_msg_free(answer); + gras_msg_free(msg); + + /* Do the saturation until we get a SAT_STOP message or until we timeout the whole XP*/ + start=gras_time(); + while (gras_msg_wait(0,GRASMSG_SAT_STOP,&msg)==timeout_error && + gras_time()-start < timeout) { + if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) { + fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode)); + /* our error message do not interess anyone. SAT_STOP will do nothing. */ + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + } + if (gras_time()-start > timeout) { + fprintf(stderr,"The saturation experiment did timeout. Stop it NOW\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + /* Handle the SAT_STOP which broke the previous while */ + + if ((errcode=gras_msg_new_and_send(sock, GRASMSG_SAT_END,0))) { + fprintf(stderr,"cbSatStart(): Cannot tell peer to stop saturation\n"); + + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Sending SAT_END to peer failed.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + if ((errcode=gras_msg_wait(60,GRASMSG_SAT_ENDED,&answer))) { + fprintf(stderr,"cbSatStart(): Peer didn't ACK the end\n"); + + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Receiving SAT_ENDED from peer failed.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + no_error,""); + + gras_sock_close(sock); + gras_rawsock_close(raw); + gras_msg_free(answer); + gras_msg_free(msg); + + return 1; +} + +int grasbw_cbSatBegin(gras_msg_t *msg) { + gras_rawsock_t *raw; + gras_error_t errcode; + double start; /* timer */ + /* request */ + unsigned int msgSize=gras_msg_ctn(msg,0,0,SatExp_t).msgSize; + unsigned int timeout=gras_msg_ctn(msg,0,0,SatExp_t).timeout; + /* answer */ + SatExp_t *request; + msgError_t *error; + + if (!(request=(SatExp_t*)malloc(sizeof(SatExp_t))) || + !(error=(msgError_t *)malloc(sizeof(msgError_t)))) { + fprintf(stderr,"cbSatBegin(): Malloc error\n"); + grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2, + "cbSatBegin: Severe error: Cannot send error status to requester!!\n", + malloc_error,"Malloc error"); + return 1; + } + + if ((errcode=gras_rawsock_server_open(6666,8000,msgSize,&raw))) { + fprintf(stderr,"cbSatBegin(): Error %s encountered while opening a raw socket\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2, + "cbSatBegin: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot open raw socket"); + return 1; + } + request->port=gras_rawsock_get_peer_port(raw); + request->msgSize=msgSize; + error->errcode=no_error; + error->errmsg[0]='\0'; + if ((errcode=gras_msg_new_and_send(msg->sock,GRASMSG_SAT_BEGUN,2, + error,1, + request,1))) { + fprintf(stderr,"cbSatBegin(): Error %s encountered while send ACK to peer\n", + gras_error_name(errcode)); + return 1; + } + gras_msg_free(msg); + + start=gras_time(); + while (gras_msg_wait(0,GRASMSG_SAT_END,&msg)==timeout_error && + gras_time() - start < timeout) { + errcode=gras_rawsock_recv(raw,msgSize,msgSize,1); + if (errcode != timeout_error && errcode != no_error) { + fprintf(stderr,"cbSatBegin: Failure %s during raw receive\n",gras_error_name(errcode)); + /* our error message do not interess anyone. SAT_END will do nothing. */ + /* (if timeout'ed, it may be because the sender stopped emission. so survive it) */ + return 1; + } + } + if (gras_time()-start > timeout) { + fprintf(stderr,"The saturation experiment did timeout. Stop it NOW.\n"); + gras_rawsock_close(raw); + return 1; + } + + grasRepportError(msg->sock,GRASMSG_SAT_ENDED,1, + "cbSatBegin: Cannot send SAT_ENDED.\n", + no_error,""); + gras_rawsock_close(raw); + gras_msg_free(msg); + return 1; +} + +gras_error_t grasbw_saturate_stop(const char* from_name,unsigned int from_port, + const char* to_name,unsigned int to_port) { + gras_error_t errcode; + gras_sock_t *sock; + gras_msg_t *answer; + + if((errcode=gras_sock_client_open(from_name,from_port,&sock))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while contacting peer\n", + gras_error_name(errcode)); + return errcode; + } + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_STOP,0))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while sending request\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STOPPED,&answer))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while receiving ACK\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"saturate_stop(): Peer reported error %s (%s).\n", + gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return errcode; + } + + gras_msg_free(answer); + gras_sock_close(sock); + + return no_error; +} +#endif diff --git a/src/amok/Bandwidth/bandwidth_private.h b/src/amok/Bandwidth/bandwidth_private.h new file mode 100644 index 0000000000..79dbf6e916 --- /dev/null +++ b/src/amok/Bandwidth/bandwidth_private.h @@ -0,0 +1,70 @@ +/* $Id$ */ + +/* bandwidth - network bandwidth tests facilities */ + +/* module's private interface masked even to other parts of AMOK. */ + +/* Authors: Martin Quinson */ +/* Copyright (C) 2003, 2004 the OURAGAN project. */ + +/* This program is free software; you can redistribute it and/or modify it + under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef AMOK_BANDWIDTH_PRIVATE_H +#define AMOK_BANDWIDTH_PRIVATE_H + +#include "gras.h" +#include "amok/bandwidth.h" + +/** + * bw_request_t: + * + * Request for a BW experiment. + * If host==NULL, it should be between the sender and the receiver. + * If not, it should be between between the receiver and @host (3-tiers). + */ +typedef struct { + gras_host_t host; /* host+raw socket to use */ + unsigned int buf_size; + unsigned int exp_size; + unsigned int msg_size; +} s_bw_request_t,*bw_request_t; + +/** + * bw_res_t: + * + * Result of a BW experiment (payload when answering). + * if err.msg != NULL, it wasn't sucessful. Check err.msg and err.code to see why. + * else + */ +typedef struct { + s_amok_remoterr_t err; + unsigned int timestamp; + double seconds; + double bw; +} s_bw_res,*bw_res_t; + + +/** + * sat_request_t: + * + * Description of a saturation experiment (payload asking some host to collaborate for that) + */ +typedef struct { + gras_host_t host; /* host+raw socket to use */ + unsigned int msg_size; + unsigned int timeout; +} s_sat_request_t,*sat_request_t; + +/* Prototypes of local callbacks */ +int amok_bw_cb_bw_handshake(gras_socket_t expeditor, + void *payload); +int amok_bw_cb_bw_request(gras_socket_t expeditor, + void *payload); + +int amok_bw_cb_sat_start(gras_socket_t expeditor, + void *payload); +int amok_bw_cb_sat_begin(gras_socket_t expeditor, + void *payload); + +#endif /* AMOK_BANDWIDTH_PRIVATE_H */ diff --git a/src/amok/Bandwidth/saturate.c b/src/amok/Bandwidth/saturate.c new file mode 100644 index 0000000000..f58c8c90d4 --- /dev/null +++ b/src/amok/Bandwidth/saturate.c @@ -0,0 +1,350 @@ +/* $Id$ */ + +/* amok_saturate - Link saturating facilities (for ALNeM's BW testing) */ + +/* Authors: Martin Quinson */ +/* Copyright (C) 2003, 2004 the OURAGAN project. */ + +/* This program is free software; you can redistribute it and/or modify it + under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "amok/Bandwidth/bandwidth_private.h" + +GRAS_LOG_EXTERNAL_CATEGORY(bw); +GRAS_LOG_DEFAULT_CATEGORY(bw); + +#if 0 +/* *************************************************************************** + * Link saturation + * ***************************************************************************/ + +gras_error_t grasbw_saturate_start(const char* from_name,unsigned int from_port, + const char* to_name,unsigned int to_port, + unsigned int msgSize, unsigned int timeout) { + gras_sock_t *sock; + gras_error_t errcode; + /* The request */ + SatExp_t *request; + msgHost_t *target; + /* answer */ + gras_msg_t *answer; + + if((errcode=gras_sock_client_open(from_name,from_port,&sock))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while contacting peer\n", + __FILE__,__LINE__,gras_error_name(errcode)); + return errcode; + } + if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t))) || + !(target=(msgHost_t*)malloc(sizeof(msgHost_t)))) { + fprintf(stderr,"%s:%d:saturate_start(): Malloc error\n",__FILE__,__LINE__); + gras_sock_close(sock); + return malloc_error; + } + + request->timeout=timeout; + request->msgSize=msgSize; + + strcpy(target->host,to_name); + target->port=to_port; + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_START, 2, + target,1, + request,1))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while sending the request.\n", + __FILE__,__LINE__,gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STARTED,&answer))) { + fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while waiting for the ACK.\n", + __FILE__,__LINE__,gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"%s:%d:saturate_start(): Peer reported error %s (%s).\n", + __FILE__,__LINE__,gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return errcode; + } + + gras_msg_free(answer); + gras_sock_close(sock); + return no_error; +} + +int grasbw_cbSatStart(gras_msg_t *msg) { + gras_rawsock_t *raw; + gras_sock_t *sock; + gras_error_t errcode; + double start; /* time to timeout */ + + /* specification of the test to run */ + char* to_name=gras_msg_ctn(msg,0,0,msgHost_t).host; + unsigned int to_port=gras_msg_ctn(msg,0,0,msgHost_t).port; + + unsigned int msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize; + unsigned int timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout; + unsigned int raw_port; + + /* The request */ + SatExp_t *request; + /* answer */ + gras_msg_t *answer; + + /* + fprintf(stderr,"grasbw_cbSatStart(sd=%p)\n",msg->sock); + fprintf(stderr,"(server=%d,raw=%d,fromPID=%d,toPID=%d,toHost=%p,toPort=%d,toChan=%d)\n", + msg->sock->server_sock,msg->sock->raw_sock,msg->sock->from_PID, + msg->sock->to_PID,msg->sock->to_host,msg->sock->to_port,msg->sock->to_chan); + */ + + /* Negociate the saturation with the peer */ + if((errcode=gras_sock_client_open(to_name,to_port,&sock))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while contacting peer\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot contact peer.\n"); + return 1; + } + if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t)))) { + fprintf(stderr,"cbSatStart(): Malloc error\n"); + gras_sock_close(sock); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + malloc_error,"Cannot build request.\n"); + return 1; + } + + request->timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout; + request->msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize; + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_BEGIN, 1, + request,1))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while sending the request.\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot send request.\n"); + gras_sock_close(sock); + return 1; + } + + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_BEGUN,&answer))) { + fprintf(stderr,"cbSatStart(): Error %s encountered while waiting for the ACK.\n", + gras_error_name(errcode)); + gras_sock_close(sock); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode, + "Cannot receive the ACK.\n"); + return 1; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"cbSatStart(): Peer reported error %s (%s).\n", + gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode, + "Peer repported '%s'.\n",gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return 1; + } + + raw_port=gras_msg_ctn(answer,1,0,SatExp_t).port; + + if ((errcode=gras_rawsock_client_open(to_name,raw_port,msgSize,&raw))) { + fprintf(stderr,"cbSatStart(): Error %s while opening raw socket to %s:%d.\n", + gras_error_name(errcode),to_name,gras_msg_ctn(answer,1,0,SatExp_t).port); + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot open raw socket.\n"); + gras_sock_close(sock); + return 1; + } + + /* send a train of data before repporting that XP is started */ + if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) { + fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot raw send.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + no_error,"Saturation started"); + gras_msg_free(answer); + gras_msg_free(msg); + + /* Do the saturation until we get a SAT_STOP message or until we timeout the whole XP*/ + start=gras_time(); + while (gras_msg_wait(0,GRASMSG_SAT_STOP,&msg)==timeout_error && + gras_time()-start < timeout) { + if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) { + fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode)); + /* our error message do not interess anyone. SAT_STOP will do nothing. */ + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + } + if (gras_time()-start > timeout) { + fprintf(stderr,"The saturation experiment did timeout. Stop it NOW\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + /* Handle the SAT_STOP which broke the previous while */ + + if ((errcode=gras_msg_new_and_send(sock, GRASMSG_SAT_END,0))) { + fprintf(stderr,"cbSatStart(): Cannot tell peer to stop saturation\n"); + + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Sending SAT_END to peer failed.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + + if ((errcode=gras_msg_wait(60,GRASMSG_SAT_ENDED,&answer))) { + fprintf(stderr,"cbSatStart(): Peer didn't ACK the end\n"); + + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + errcode,"Receiving SAT_ENDED from peer failed.\n"); + gras_sock_close(sock); + gras_rawsock_close(raw); + return 1; + } + grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1, + "cbSatStart: Severe error: Cannot send error status to requester!!\n", + no_error,""); + + gras_sock_close(sock); + gras_rawsock_close(raw); + gras_msg_free(answer); + gras_msg_free(msg); + + return 1; +} + +int grasbw_cbSatBegin(gras_msg_t *msg) { + gras_rawsock_t *raw; + gras_error_t errcode; + double start; /* timer */ + /* request */ + unsigned int msgSize=gras_msg_ctn(msg,0,0,SatExp_t).msgSize; + unsigned int timeout=gras_msg_ctn(msg,0,0,SatExp_t).timeout; + /* answer */ + SatExp_t *request; + msgError_t *error; + + if (!(request=(SatExp_t*)malloc(sizeof(SatExp_t))) || + !(error=(msgError_t *)malloc(sizeof(msgError_t)))) { + fprintf(stderr,"cbSatBegin(): Malloc error\n"); + grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2, + "cbSatBegin: Severe error: Cannot send error status to requester!!\n", + malloc_error,"Malloc error"); + return 1; + } + + if ((errcode=gras_rawsock_server_open(6666,8000,msgSize,&raw))) { + fprintf(stderr,"cbSatBegin(): Error %s encountered while opening a raw socket\n", + gras_error_name(errcode)); + grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2, + "cbSatBegin: Severe error: Cannot send error status to requester!!\n", + errcode,"Cannot open raw socket"); + return 1; + } + request->port=gras_rawsock_get_peer_port(raw); + request->msgSize=msgSize; + error->errcode=no_error; + error->errmsg[0]='\0'; + if ((errcode=gras_msg_new_and_send(msg->sock,GRASMSG_SAT_BEGUN,2, + error,1, + request,1))) { + fprintf(stderr,"cbSatBegin(): Error %s encountered while send ACK to peer\n", + gras_error_name(errcode)); + return 1; + } + gras_msg_free(msg); + + start=gras_time(); + while (gras_msg_wait(0,GRASMSG_SAT_END,&msg)==timeout_error && + gras_time() - start < timeout) { + errcode=gras_rawsock_recv(raw,msgSize,msgSize,1); + if (errcode != timeout_error && errcode != no_error) { + fprintf(stderr,"cbSatBegin: Failure %s during raw receive\n",gras_error_name(errcode)); + /* our error message do not interess anyone. SAT_END will do nothing. */ + /* (if timeout'ed, it may be because the sender stopped emission. so survive it) */ + return 1; + } + } + if (gras_time()-start > timeout) { + fprintf(stderr,"The saturation experiment did timeout. Stop it NOW.\n"); + gras_rawsock_close(raw); + return 1; + } + + grasRepportError(msg->sock,GRASMSG_SAT_ENDED,1, + "cbSatBegin: Cannot send SAT_ENDED.\n", + no_error,""); + gras_rawsock_close(raw); + gras_msg_free(msg); + return 1; +} + +gras_error_t grasbw_saturate_stop(const char* from_name,unsigned int from_port, + const char* to_name,unsigned int to_port) { + gras_error_t errcode; + gras_sock_t *sock; + gras_msg_t *answer; + + if((errcode=gras_sock_client_open(from_name,from_port,&sock))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while contacting peer\n", + gras_error_name(errcode)); + return errcode; + } + + if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_STOP,0))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while sending request\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STOPPED,&answer))) { + fprintf(stderr,"saturate_stop(): Error %s encountered while receiving ACK\n", + gras_error_name(errcode)); + gras_sock_close(sock); + return errcode; + } + + if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) { + fprintf(stderr,"saturate_stop(): Peer reported error %s (%s).\n", + gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg); + gras_msg_free(answer); + gras_sock_close(sock); + return errcode; + } + + gras_msg_free(answer); + gras_sock_close(sock); + + return no_error; +} +#endif