void FC_handle_message( sys_scatter *scat ) { int16 *cur_fc_buf; packet_header *pack_ptr; proc dummy_proc; int my_index; int16 temp_window,temp_personal_window; configuration *Cn; Cn = Conf_ref(); pack_ptr = (packet_header *)scat->elements[0].buf; if ( ! Conf_get_dangerous_monitor_state() ) { Alarm( FLOW_CONTROL, "FC_handle_message: Request to change flow control from (%d.%d.%d.%d) denied. Monitor in safe mode\n", IP1(pack_ptr->proc_id), IP2(pack_ptr->proc_id), IP3(pack_ptr->proc_id), IP4(pack_ptr->proc_id) ); return; } if( ! ( pack_ptr->memb_id.proc_id == 15051963 && Conf_id_in_conf( Cn, pack_ptr->proc_id ) != -1 ) ) { Alarm( FLOW_CONTROL, "FC_handle_message: Illegal monitor request\n"); return; } cur_fc_buf = (int16 *)scat->elements[1].buf; my_index = Conf_proc_by_id( Conf_my().id, &dummy_proc ); if( Same_endian( pack_ptr->type ) ) { temp_window = cur_fc_buf[Conf_num_procs( Cn )]; temp_personal_window = cur_fc_buf[my_index]; }else{ temp_window = Flip_int16( cur_fc_buf[Conf_num_procs( Cn )] ); temp_personal_window = Flip_int16( cur_fc_buf[my_index] ); } if( temp_window != -1 ) Window = temp_window; if( temp_personal_window != -1 ) Personal_window = temp_personal_window; GlobalStatus.window = Window; GlobalStatus.personal_window = Personal_window; Alarm( FLOW_CONTROL, "FC_handle_message: Got monitor mess, Window %d Personal %d\n", Window, Personal_window ); }
void Prot_handle_token(channel fd, int dummy, void *dummy_p) { int new_ptr; int num_retrans, num_allowed, num_sent; int flow_control; char *new_rtr; ring_rtr *ring_rtr_ptr; int32 rtr_proc_id; int16 rtr_seg_index; int32 val; int retrans_allowed; /* how many of my retrans are allowed on token */ int i, ret; /* int r1,r2;*/ ret = Net_recv_token( fd, &New_token ); /* from another monitor component */ if( ret == 0 ) return; /* delete random r1 = ((-My.id)%17)+3; r2 = get_rand() % (r1+3 ); if ( r2 == 0 ) return; */ Alarm( DEBUG, "Received Token\n"); /* check if it is a regular token */ if( Is_form( Token->type ) ) { Alarm(PROTOCOL, "it is a Form Token.\n"); Memb_handle_token( &New_token ); return; } /* The Veto property for tokens - swallow this token */ if( ! Memb_token_alive() ) { Alarm(PROTOCOL, "Prot_handle_token: Veto Property. Memb not alive.\n"); return; } if( ret != sizeof(token_header) + Token->rtr_len ) { Alarm( PRINT, "Prot_handle_token: recv token len is %d, should be %d\n", ret,sizeof(token_header) + Token->rtr_len ); return; } if( !Same_endian( Token->type ) ) Flip_token_body( New_token.elements[1].buf, Token ); /* Deal with wrapping seq values (2^32) by triggering a membership by dropping the token */ if( (Memb_state() != EVS ) && (Token->seq > MAX_WRAP_SEQUENCE_VALUE ) ) { Alarm( PRINT, "Prot_handle_token: Token Sequence number (%ld) approaching 2^31 so trigger membership to reset it.\n", Token->seq); return; } if( Conf_leader( Memb_active_ptr() ) == My.id ) { if( Get_arq(Token->type) != Get_arq(Last_token->type) ) { Alarm( PROTOCOL, "Prot_handle_token: leader swallowing token %d %d %d\n", Get_arq(Token->type),Get_retrans(Token->type),Get_arq(Last_token->type) ); /* received double token - swallow it */ return; } }else{ if( Get_arq(Token->type) == Get_arq(Last_token->type) ) { if( Get_retrans(Token->type) > Get_retrans(Last_token->type) ) { val = Get_retrans(Token->type); Last_token->type = Set_retrans(Last_token->type,val); /* asked to send token again (almost lost) */ Alarm( PROTOCOL, "Prot_handle_token: not leader, asked to retrans %d %d\n", Get_arq(Token->type), val ); Prot_token_hurry(); }else{ Alarm( PROTOCOL, "Prot_handle_token: not leader, swallow same token %d %d\n", Get_arq(Token->type), Get_retrans(Token->type) ); } return; } else if ( Get_arq(Token->type) != ( ( Get_arq( Last_token->type ) + 1 ) % 0x10 ) ) { Alarm( PROTOCOL, "Prot_handle_token: not leader, swallowing very outdated token: ARQ(%d) RETRANS(%d) vs. Last ARQ(%d)\n", Get_arq(Token->type), Get_retrans(Token->type), Get_arq(Last_token->type) ); return; } else { if ( Get_retrans(Token->type) > 0 ) { GlobalStatus.token_hurry++; } } } if( Highest_seq < Token->seq ) Highest_seq = Token->seq; /* Handle retransmissions */ num_retrans = Answer_retrans( &new_ptr, &rtr_proc_id, &rtr_seg_index ); GlobalStatus.retrans += num_retrans; new_rtr = New_token.elements[1].buf; /* Handle new packets */ flow_control = (int) Token->flow_control; num_allowed = FC_allowed( flow_control, num_retrans ); num_sent = Send_new_packets( num_allowed ); GlobalStatus.packet_sent += num_sent; /* Flow control calculations */ Token->flow_control = Token->flow_control - Last_num_retrans - Last_num_sent + num_retrans + num_sent; Last_num_retrans = num_retrans; Last_num_sent = num_sent; /* Prepare my retransmission requests */ for( i = My_aru+1; i <= Highest_seq; i++ ) { if( ! Packets[i & PACKET_MASK].exist ) break; My_aru++; } GlobalStatus.my_aru = My_aru; if( My_aru < Highest_seq ) { /* Compute how many of my retransmission requests are possible to fit */ retrans_allowed = ( sizeof( token_body ) - new_ptr - sizeof( ring_rtr ) ) / sizeof( int32 ); if( retrans_allowed > 1 ) { ring_rtr_ptr = (ring_rtr *)&new_rtr[new_ptr]; ring_rtr_ptr->memb_id = Memb_id(); ring_rtr_ptr->proc_id = rtr_proc_id; ring_rtr_ptr->seg_index = rtr_seg_index; ring_rtr_ptr->num_seq = 0; new_ptr += sizeof(ring_rtr); for( i=My_aru+1; i <= Highest_seq && retrans_allowed > 0; i++, retrans_allowed-- ) { if( ! Packets[i & PACKET_MASK].exist ) { memcpy( &new_rtr[new_ptr], &i, sizeof(int32) ); new_ptr += sizeof(int32); ring_rtr_ptr->num_seq++; } } } } if( Memb_state() == EVS ) { if( My_aru == Highest_seq ) { My_aru = Last_seq; Memb_commit(); } } Token->rtr_len = new_ptr; New_token.elements[1].len = new_ptr; /* Calculating Token->aru and Set_aru */ if( ( Token->aru == Set_aru ) || ( Token->aru_last_id == My.id ) || ( Token->aru == Token->seq ) ) { Token->aru = My_aru; Token->aru_last_id = My.id; if( My_aru < Highest_seq ) Set_aru = My_aru; else Set_aru = -1; }else if( Token->aru > My_aru ) { Token->aru = My_aru; Token->aru_last_id = My.id; Set_aru = My_aru; }else{ Set_aru = -1; } Token->proc_id = My.id; if( Memb_state() != EVS ) Token->seq = Highest_seq; if( Conf_leader( Memb_active_ptr() ) == My.id ) { val = Get_arq( Token->type ); val = (val + 1)% 0x10; Token->type = Set_arq( Token->type, val ); Token->type = Set_retrans( Token->type, 0 ); } /* Send token */ if( ! ( Conf_leader( Memb_active_ptr() ) == My.id && To_hold_token() ) ) { /* sending token */ Net_send_token( &New_token ); /* ### Bug fix for SGIs */ #ifdef ARCH_SGI_IRIX Net_send_token( &New_token ); #endif /* ARCH_SGI_IRIX */ if( Get_retrans( Token->type ) > 1 ) { /* problems */ Net_send_token( &New_token ); Net_send_token( &New_token ); } } Token_rounds++; if( Conf_leader( Memb_active_ptr() ) == My.id ) E_queue( Prot_token_hurry, 0, NULL, Hurry_timeout ); E_queue( Memb_token_loss, 0, NULL, Token_timeout ); /* calculating Aru */ if( Token->aru > Last_token->aru ) Aru = Last_token->aru; else Aru = Token->aru; if( Highest_seq == Aru ) Token_counter++; else Token_counter = 0; dispose( Last_token ); Last_token = Token; New_token.elements[0].buf = (char *) new(TOKEN_HEAD_OBJ); New_token.elements[1].len = sizeof(token_body); Token = (token_header *)New_token.elements[0].buf; /* Deliver & discard packets */ Discard_packets(); Deliver_agreed_packets(); Deliver_reliable_packets( Highest_seq-num_sent+1, num_sent ); if( Memb_state() == EVS && Token_rounds > MAX_EVS_ROUNDS ) { Alarmp( SPLOG_ERROR, PRINT, "Prot_handle_token: BUG WORKAROUND: Too many rounds in EVS state; swallowing token; state:\n" ); Alarmp( SPLOG_ERROR, PRINT, "\tAru: %d\n", Aru ); Alarmp( SPLOG_ERROR, PRINT, "\tMy_aru: %d\n", My_aru ); Alarmp( SPLOG_ERROR, PRINT, "\tHighest_seq: %d\n", Highest_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tHighest_fifo_seq: %d\n", Highest_fifo_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_discarded: %d\n", Last_discarded ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_delivered: %d\n", Last_delivered ); Alarmp( SPLOG_ERROR, PRINT, "\tLast_seq: %d\n", Last_seq ); Alarmp( SPLOG_ERROR, PRINT, "\tToken_rounds: %d\n", Token_rounds ); Alarmp( SPLOG_ERROR, PRINT, "Last Token:\n" ); Alarmp( SPLOG_ERROR, PRINT, "\ttype: 0x%x\n", Last_token->type ); Alarmp( SPLOG_ERROR, PRINT, "\ttransmiter_id: %d\n", Last_token->transmiter_id ); Alarmp( SPLOG_ERROR, PRINT, "\tseq: %d\n", Last_token->seq ); Alarmp( SPLOG_ERROR, PRINT, "\tproc_id: %d\n", Last_token->proc_id ); Alarmp( SPLOG_ERROR, PRINT, "\taru: %d\n", Last_token->aru ); Alarmp( SPLOG_ERROR, PRINT, "\taru_last_id: %d\n", Last_token->aru_last_id ); Alarmp( SPLOG_ERROR, PRINT, "\tflow_control: %d\n", Last_token->flow_control ); Alarmp( SPLOG_ERROR, PRINT, "\trtr_len: %d\n", Last_token->rtr_len ); Alarmp( SPLOG_ERROR, PRINT, "\tconf_hash: %d\n", Last_token->conf_hash ); Memb_token_loss(); } GlobalStatus.highest_seq = Highest_seq; GlobalStatus.aru = Aru; GlobalStatus.token_rounds = Token_rounds; }
static void Report_message(mailbox fd, int dummy, void *dummy_p) { proc p; proc leader_p; int ret; int ret1,ret2; static int32 last_mes; static int32 last_aru; static int32 last_sec; last_mes = GlobalStatus.message_delivered; last_aru = GlobalStatus.aru; last_sec = GlobalStatus.sec; ret = DL_recv( fd, &Report_scat ); if( ret <= 0 ) { Alarm( DEBUG, "Report_messsage: DL_recv failed with ret %d, errno %d\n", ret, sock_errno); return; } if( !Same_endian( Report_pack.type ) ) { GlobalStatus.sec = Flip_int32( GlobalStatus.sec ); GlobalStatus.state = Flip_int32( GlobalStatus.state ); GlobalStatus.gstate = Flip_int32( GlobalStatus.gstate ); GlobalStatus.packet_sent = Flip_int32( GlobalStatus.packet_sent ); GlobalStatus.packet_recv = Flip_int32( GlobalStatus.packet_recv ); GlobalStatus.packet_delivered = Flip_int32( GlobalStatus.packet_delivered ); GlobalStatus.retrans = Flip_int32( GlobalStatus.retrans ); GlobalStatus.u_retrans = Flip_int32( GlobalStatus.u_retrans ); GlobalStatus.s_retrans = Flip_int32( GlobalStatus.s_retrans ); GlobalStatus.b_retrans = Flip_int32( GlobalStatus.b_retrans ); GlobalStatus.aru = Flip_int32( GlobalStatus.aru ); GlobalStatus.my_aru = Flip_int32( GlobalStatus.my_aru ); GlobalStatus.highest_seq = Flip_int32( GlobalStatus.highest_seq ); GlobalStatus.token_hurry = Flip_int32( GlobalStatus.token_hurry ); GlobalStatus.token_rounds = Flip_int32( GlobalStatus.token_rounds ); GlobalStatus.my_id = Flip_int32( GlobalStatus.my_id ); GlobalStatus.leader_id = Flip_int32( GlobalStatus.leader_id ); GlobalStatus.message_delivered = Flip_int32( GlobalStatus.message_delivered ); GlobalStatus.membership_changes = Flip_int16( GlobalStatus.membership_changes); GlobalStatus.num_procs = Flip_int16( GlobalStatus.num_procs ); GlobalStatus.num_segments = Flip_int16( GlobalStatus.num_segments ); GlobalStatus.window = Flip_int16( GlobalStatus.window ); GlobalStatus.personal_window = Flip_int16( GlobalStatus.personal_window ); GlobalStatus.accelerated_ring = Flip_int16( GlobalStatus.accelerated_ring ); GlobalStatus.accelerated_window = Flip_int16( GlobalStatus.accelerated_window ); GlobalStatus.num_sessions = Flip_int16( GlobalStatus.num_sessions ); GlobalStatus.num_groups = Flip_int16( GlobalStatus.num_groups ); GlobalStatus.major_version = Flip_int16( GlobalStatus.major_version ); GlobalStatus.minor_version = Flip_int16( GlobalStatus.minor_version ); GlobalStatus.patch_version = Flip_int16( GlobalStatus.patch_version ); } printf("\n============================\n"); ret1 = Conf_proc_by_id( GlobalStatus.my_id, &p ); ret2 = Conf_proc_by_id( GlobalStatus.leader_id, &leader_p ); if( ret1 < 0 ) { printf("Report_message: Skiping illegal status \n"); printf("==================================\n"); return; } printf("Status at %s V%2d.%02d.%2d (state %d, gstate %d) after %d seconds :\n",p.name, GlobalStatus.major_version,GlobalStatus.minor_version,GlobalStatus.patch_version, GlobalStatus.state, GlobalStatus.gstate, GlobalStatus.sec); if( ret2 < 0 ) printf("Membership : %d procs in %d segments, leader is %d, ", GlobalStatus.num_procs,GlobalStatus.num_segments,GlobalStatus.leader_id); else printf("Membership : %d procs in %d segments, leader is %s, ", GlobalStatus.num_procs,GlobalStatus.num_segments,leader_p.name); if (GlobalStatus.accelerated_ring == 0) printf("regular protocol\n"); else printf("accelerated protocol\n"); printf("rounds : %7d\ttok_hurry : %7d\tmemb change: %7d\n",GlobalStatus.token_rounds,GlobalStatus.token_hurry,GlobalStatus.membership_changes); printf("sent pack: %7d\trecv pack : %7d\tretrans : %7d\n",GlobalStatus.packet_sent,GlobalStatus.packet_recv,GlobalStatus.retrans); printf("u retrans: %7d\ts retrans : %7d\tb retrans : %7d\n",GlobalStatus.u_retrans,GlobalStatus.s_retrans,GlobalStatus.b_retrans); printf("My_aru : %7d\tAru : %7d\tHighest seq: %7d\n",GlobalStatus.my_aru,GlobalStatus.aru, GlobalStatus.highest_seq); printf("Sessions : %7d\tGroups : %7d\tWindow : %7d\n",GlobalStatus.num_sessions,GlobalStatus.num_groups,GlobalStatus.window); printf("Deliver M: %7d\tDeliver Pk: %7d\tP/A Window : %7d/%d\n",GlobalStatus.message_delivered,GlobalStatus.packet_delivered,GlobalStatus.personal_window,GlobalStatus.accelerated_window); printf("Delta Mes: %7d\tDelta Pk : %7d\tDelta sec : %7d\n",GlobalStatus.message_delivered - last_mes,GlobalStatus.aru - last_aru,GlobalStatus.sec - last_sec); printf("==================================\n"); printf("\n"); printf("Monitor> "); fflush(stdout); }