Exemple #1
0
/* 
 * The following routine will be called once (only) before any other   
 * entity B routines are called. You can use it to do any initialization 
 */
void B_init() {
  struct pkt packet;
  packet.seqnum = 0;
  packet.acknum = ACK;
  packet.checksum = 0;
  packet.checksum = genchecksum(packet);
  Bpastack = packet;
}
Exemple #2
0
/* entity A routines are called. You can use it to do any initialization */
void A_init() {
  /////new stuff
  struct pkt packet;
  packet.seqnum = 0;
  packet.acknum = ACK;
  packet.checksum = 0;
  packet.checksum = genchecksum(packet);
  Apastack = packet;
  /////old stuff
}
Exemple #3
0
/*
 * The following functions generates a checksum for the packet by using fletchers algorithms on the binary data of the structure, using blocks of 2 bytes*/
int iscorrupt(struct pkt packet) {
  int checksum1 = packet.checksum;
  packet.checksum = 0;
  int checksum2 = genchecksum(packet);
  //printf("checksum1: %d checksum2: %d\n",checksum1,checksum2);
  if (checksum1 != checksum2) {
    //printf("Packet is corrupted\n");
    //printf("Total packets corrupted %d\n",corrupted);
    return TRUE;
  }
  packet.checksum = checksum1;
  return FALSE;
}
Exemple #4
0
/*
 * B_input(packet),where packet is a structure of type pkt. This routine 
 * will be called whenever a packet sent from the A-side (i.e., as a result 
 * of a tolayer3() being done by a A-side procedure) arrives at the B-side. 
 * packet is the (possibly corrupted) packet sent from the A-side.
 */
void B_input(struct pkt packet) {
  struct pkt ack;
  if (iscorrupt(packet)) {
    return;
  }
  
  if (packet.acknum == DATAACK) {  
    if (!iscorrupt(packet) && packet.seqnum != Bexpectedseqnum) { //wrong seq num
      ack = Bpastack;
      tolayer3(BEntity,ack); 
      return;
    }
    if (!iscorrupt(packet) && packet.seqnum == Bexpectedseqnum) { //right seqnum
      ack.checksum = 0;
      ack.seqnum = packet.seqnum;
      ack.acknum = ACK;
      memcpy(ack.payload,packet.payload,MESSAGE_LENGTH);
      ack.checksum = genchecksum(ack);
      Bpastack = ack;
      tolayer3(BEntity,ack); 
      struct msg message;
      memcpy(message.data,packet.payload,MESSAGE_LENGTH); 
      tolayer5(BEntity,message);
      Bexpectedseqnum++;
      return; 
    }
  }
////new stuff  
  if (packet.acknum == ACK) {
    if (Bbase >= (packet.seqnum + 1)) {
      if (packet.seqnum + 1 == Bnextseqnum) {
	stopTimer(BEntity);
      }
      return;
    }
    Bbase = packet.seqnum + 1;
    if (Bbase == Bnextseqnum) {
      stopTimer(BEntity);
    }
    else {
      stopTimer(BEntity);
      startTimer(BEntity,TIMERAMT);
    }
  }
////old stuff  
  
}
Exemple #5
0
void A_output(struct msg message) {
  Atemp = (struct pkt*) malloc(sizeof(struct pkt));
  memcpy(Atemp->payload,message.data,MESSAGE_LENGTH);
  Atemp->seqnum = Anextseqnum;
  Atemp->acknum = DATAACK;
  Atemp->checksum = 0;
  Atemp->checksum = genchecksum(*Atemp);
  Aglobalarray[Anextseqnum] = Atemp;
  if (Anextseqnum < (Abase + WINDOW_SIZE)) { //(!getTimerStatus( AEntity )) { //will succeed if timer is off
    tolayer3(AEntity,*Atemp);
    if (Abase == Anextseqnum) {
      startTimer(AEntity,TIMERAMT);
    }
  }
  Anextseqnum++;
  return;
}
Exemple #6
0
/*
 * Just like A_output, but residing on the B side.  USED only when the 
 * implementation is bi-directional.
 */
void B_output(struct msg message)  {
//////new stuff
  Btemp = (struct pkt*) malloc(sizeof(struct pkt));
  memcpy(Btemp->payload,message.data,MESSAGE_LENGTH);
  Btemp->seqnum = Bnextseqnum;
  Btemp->acknum = DATAACK;
  Btemp->checksum = 0;
  Btemp->checksum = genchecksum(*Btemp);
  Bglobalarray[Bnextseqnum] = Btemp;
  if (Bnextseqnum < (Bbase + WINDOW_SIZE)) { //(!getTimerStatus( AEntity )) { //will succeed if timer is off
    tolayer3(BEntity,*Btemp);
    if (Bbase == Bnextseqnum) {
      startTimer(BEntity,TIMERAMT);
    }
  }
  Bnextseqnum++;
  return;
/////old stuff  

}
static int
replay_line(mr_unit_t *un, raid_rplylst_t *eachp, raid_rplybuf_t *rplybuf)
{
	raid_pwhdr_t	*pwhdr1, *pwhdr2;
	raid_rplylst_t	*eachpn;
	int		i;
	int		cnt;
	diskaddr_t	blkno;
	uint_t		blkcnt;
	long long	id;
	int		dsum;
	int		error;
	int		colcnt, col, col2;
	int		down;

	if (eachp->rpl_id == 0)
		return (0);
	/*
	 * check: 1 - enough equal ids
	 *	  2 - all have same columncnt
	 *	  3 - all have same blkno
	 *	  4 - all have same blkcnt
	 *
	 * read each and check the checksum
	 * write each
	 */

	cnt = eachp->rpl_colcnt;
	id = eachp->rpl_id;
	pwhdr1 = &eachp->rpl_pwhdr1;
	blkno = pwhdr1->rpw_blkno;
	blkcnt = pwhdr1->rpw_blkcnt;

	error = raid_pw_read(un, eachp->rpl_column1, eachp->rpl_slot1, rplybuf);
	dsum = genchecksum(rplybuf->rpl_data + DEV_BSIZE,
	    dbtob(pwhdr1->rpw_blkcnt));

	if (dsum != pwhdr1->rpw_sum)
		return (0);

	if (error) {
		if (error == RAID_RPLY_COMPREPLAY)
			return (0);
		else
			return (1);
	}

	eachpn = eachp->rpl_next;
	for (i = 1; i < cnt; i++) {
		if (eachpn == NULL)
			break;
		col2 = eachpn->rpl_column1;
		ASSERT(col2 < un->un_totalcolumncnt);
		pwhdr2 = &eachpn->rpl_pwhdr1;
		if ((pwhdr2->rpw_blkno != blkno) ||
		    (pwhdr2->rpw_blkcnt != blkcnt) ||
		    (eachpn->rpl_id != id) ||
		    (pwhdr2->rpw_colcount != cnt)) {
			return (0);
		}

		error = raid_pw_read(un, col2, eachpn->rpl_slot1, rplybuf);
		dsum = genchecksum(rplybuf->rpl_data + DEV_BSIZE,
		    dbtob(pwhdr2->rpw_blkcnt));
		if (dsum != pwhdr2->rpw_sum)
			return (0);
		eachpn = eachpn->rpl_next;
	}
	colcnt = i;

	if (error)
		return (0);

	down = raid_state_cnt(un, RCS_ERRED);
	if ((i != un->un_totalcolumncnt) &&
	    (i != (un->un_totalcolumncnt - down)))
		return (0);

	/* there ara enough columns to write correctly */
	eachpn = eachp;
	for (i = 0; i < colcnt; i++) {
		col = eachpn->rpl_column1;
		error = raid_pw_read(un, col, eachpn->rpl_slot1, rplybuf);
		error = raid_pw_write(un, col, &eachpn->rpl_pwhdr1, rplybuf);
		eachpn->rpl_id = 0;
		if (error && (error != RAID_RPLY_COMPREPLAY))
			return (1);
		eachpn = eachpn->rpl_next;
	}
	return (0);
}
/*
 * NAMES:	raid_rplyeach
 * DESCRIPTION: issue a syncronous read to read a pre-write header
 * PARAMETERS:	mr_unit_t *un - pointer to the unit structure
 *		raid_rplylst_t *eachp - pointer to the replay list entry
 *		raid_rplybuf_t *rwbuf1 - pointer to the replay buffer structure
 *		raid_rplybuf_t *rwbuf2 - pointer to the replay buffer structure
 * RETURNS:
 */
static int
raid_rplyeach(
	mr_unit_t	*un,
	raid_rplylst_t	*eachp,
	raid_rplybuf_t	*rwbuf1,
	raid_rplybuf_t	*rwbuf2
)
{
	raid_pwhdr_t	*pwhp1;
	raid_pwhdr_t	*pwhp2;
	uint_t		dsum1 = 0;
	uint_t		dsum2 = 0;
	int		good_pw1 = 0;
	int		good_pw2 = 0;
	int		do_1 = 0;
	int		do_2 = 0;
	int		error = 0;

	/* First verify the normal case - two pre-write entries are all good */
	if ((eachp->rpl_pwhdr1.rpw_magic == RAID_PWMAGIC &&
	    eachp->rpl_pwhdr2.rpw_magic == RAID_PWMAGIC) &&
	    (eachp->rpl_pwhdr1.rpw_blkcnt == eachp->rpl_pwhdr2.rpw_blkcnt)) {

		ASSERT(eachp->rpl_pwhdr1.rpw_id == eachp->rpl_pwhdr2.rpw_id);

		/* read the pre-write entries */
		error = raid_pw_read(un, eachp->rpl_column1,
		    eachp->rpl_slot1, rwbuf1);
		pwhp1 = &eachp->rpl_pwhdr1;
		if (error) {
			if (error != RAID_RPLY_COMPREPLAY)
				return (error);
			good_pw1 = FALSE;
		} else {
			/* generate checksum for each pre-write entry */
			dsum1 = genchecksum(rwbuf1->rpl_data + DEV_BSIZE,
						dbtob(pwhp1->rpw_blkcnt));
			good_pw1 = (dsum1 == pwhp1->rpw_sum);
		}

		error = raid_pw_read(un, eachp->rpl_column2, eachp->rpl_slot2,
		    rwbuf2);
		pwhp2 = &eachp->rpl_pwhdr2;
		if (error) {
			if (error != RAID_RPLY_COMPREPLAY)
				return (error);
			good_pw2 = FALSE;
		} else {
			/* generate checksum for pre-write entry */
			dsum2 = genchecksum(rwbuf2->rpl_data + DEV_BSIZE,
						dbtob(pwhp2->rpw_blkcnt));
			good_pw2 = (dsum2 == pwhp2->rpw_sum);
		}

		/* verify the checksums and states */
		raid_rply_verify(un, eachp->rpl_column1, good_pw1, &do_1,
			eachp->rpl_column2, good_pw2, &do_2);

		/* write (replay) the pre-write entries */
		if (do_1) {
			error = raid_pw_write(un, eachp->rpl_column1,
			    &eachp->rpl_pwhdr1, rwbuf1);
			if (error && (error != RAID_RPLY_COMPREPLAY)) {
				return (error);
			}
		}
		if (do_2) {
			error = raid_pw_write(un, eachp->rpl_column2,
			    &eachp->rpl_pwhdr2, rwbuf2);
			if (error && (error != RAID_RPLY_COMPREPLAY)) {
				return (error);
			}
		}
		return (0);
	}
	if (eachp->rpl_pwhdr1.rpw_magic == RAID_PWMAGIC) {
		/*
		 * if partner was errored at time of write
		 * or due to open or replay, replay this entry
		 */
		if ((eachp->rpl_pwhdr1.rpw_columnnum == -1) ||
		    (! COLUMN_ISUP(un, eachp->rpl_pwhdr1.rpw_columnnum))) {
			/* read the pre-write entry */
			error = raid_pw_read(un, eachp->rpl_column1,
			    eachp->rpl_slot1, rwbuf1);
			if (error)
				return (error);
			/* generate checksum for the pre-write entry */
			pwhp1 = &eachp->rpl_pwhdr1;
			dsum1 = genchecksum(rwbuf1->rpl_data + DEV_BSIZE,
						dbtob(pwhp1->rpw_blkcnt));
			if (dsum1 == pwhp1->rpw_sum) {
				error = raid_pw_write(un, eachp->rpl_column1,
						&eachp->rpl_pwhdr1, rwbuf1);
				if (error && (error != RAID_RPLY_COMPREPLAY)) {
					return (error);
				}
			}
		}
		return (0);
	}

	return (0);
}