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 );
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);

}