          <<< SSAG::DISK$ARCH2:[NOTES$LIBRARY.SSAG]ASK_SSAG.NOTE;7 >>>
                    -< Ask the Storage Architecture Group >-
================================================================================
Note 5539.3            program to compare LBN on shadow??                 3 of 4
KERNEL::MEGARITY "I remember when Rock was young"   503 lines  18-APR-1996 14:11
                         -< Check_Shadow_Set_Data.Mar >-
--------------------------------------------------------------------------------
	.Title	Check_Shadow_Set_Data
;	.Ident	"V1.0-1"
;
;
;	This program checks the data on shadow set members and reports
;	on any LBNs which do not contain exactly the same data.
;
;	Note that this initial version can only handle shadow sets with
;	exactly two members.
;
;
;	Author:  Ian Megarity   (UK TSC - 191107)
;
	.Macro	Im$Fao_S Ctrstr,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,-
			P11,P12,P13,P14,P15, -
			?Label

	.Globl	Sys$Fao, Sys$FaoL

	.Save_Psect	Local_Block
	.Psect	ImFao$Data	Wrt,NoExe,Ovr
Fao_Descr'Label':
Fao_Length'Label':
	.Word	1000
	.Word	0
	.Address -
		Fao_Buffer'Label'
Fao_Buffer'Label':
	.Blkb	1000
Fao_Chan'Label':
	.Word	0
Fao_Msg'Label':
	.Ascid	/$FAO failure code returned ... /

	.Restore_Psect

	Movw	#1000,	Fao_Length'Label'
	$$T2 = 3
	.IRP	$$T1,  <P15,P14,P13,P12,P11,-
			P10,P9,P8,P7,P6,P5,P4,P3,P2,P1>
		.IF NB $$T1
			PUSHL	$$T1
			$$T2=$$T2+1
		.ENDC
	.ENDR
	$Pushadr Fao_Descr'Label',Context=Q
	$Pushadr Fao_Length'Label',Context=W
	$Pushadr Ctrstr,Context=Q
	Calls	#$$T2,G^Sys$Fao
	Blbs	R0,	Label
	Pushl	R0
	Pushaq	Fao_Msg'Label'
	Calls	#1,	G^Lib$Put_Output
	Popl	R0
	$Exit_S	R0

Label:
	Pushaq	Fao_Descr'Label'
	Calls	#1,	G^Lib$Put_Output

	.Endm	Im$Fao_S



	.Psect	Rw_Data	Wrt, NoExe

Disk_Size:
	.Long	0
Dvi_Iosb:
	.Long	0
	.Long	0

Dvi_Item_List:				; $GETDVI item list for SYS$INPUT:.
	.Word	4
	.Word	Dvi$_MaxBlock
	.Address -
		Disk_Size
	.Long	0

	.Word	64
	.Word	Dvi$_Shdw_Next_Mbr_Name
	.Address -
		Member_Name
	.Address -
		Member_Name_Length

	.Long	0			; $GETDVI Item list terminator.


Dvi_Item_List_2:
	.Word	64
	.Word	Dvi$_Shdw_Next_Mbr_Name
	.Address -
		Member_Name2
	.Address -
		Member_Name2_Length

	.Long	0			; $GETDVI Item list terminator.


Member_Name_Descr:
Member_Name_Length:
	.Long	64
	.Address -
		Member_Name
Member_Name:
	.Blkb	64

Member_Name2_Descr:
Member_Name2_Length:
	.Long	64
	.Address -
		Member_Name2
Member_Name2:
	.Blkb	64

Input_Descr:
Input_Length:
	.Word	255
	.Word	0
	.Address -
		Input_Buffer
Input_Buffer:
	.Blkb	255


Dev_Channel:
	.Long	0
Dev_Channel_1:
	.Long	0
Dev_Channel_2:
	.Long	0

Eof_Flag:
	.Long	0
Read_Count:
	.Long	0
Read_Block:
	.Long	0
End_Lbn:
	.Long	0
Retry_Count:
	.Long	0
Block_Count:
	.Long	0
Ios_Per_1PerCent:
	.Long	0		; # of I/Os necessary to read approx 1% of disk.
Per_Cent:
	.Long	0
One_Second:
	.Float	5.00
;
;
;
Cluster	= 127
Rec_Size = 512*Cluster

Rec_Buffer_Length:
	.Long	Rec_Size
Rec_Buff_1:
	.Blkb	Rec_size
Rec_Buff_2:
	.Blkb	Rec_size

Input_Io_Status1:
	.Word	0
Input_Io_Bytes1:
	.Word	0
	.Long	0

Input_Io_Status2:
	.Word	0
Input_Io_Bytes2:
	.Word	0
	.Long	0

Efn_1:
	.Long	0
Efn_2:
	.Long	0


	.Psect	Ro_Data,	Rd,NoExe
Ctl_1:
	.Ascid	"Members are !AS and !AS, Max Blocks value is !ZL!/"
Ctl_11:
	.Ascid	"!/Starting to check !AS at !%D"
Ctl_21:
	.Ascid	"!ZW bytes read from Disk #1"
Ctl_22:
	.Ascid	"!ZW bytes read from Disk #2"
Ctl_3:
	.Ascid	"*** Discrepancy found at block !ZL ***"
Ctl_4:
	.Ascid	"Checking block #!UL (approx !ZL%)"
Ctl_5:
	.Ascid	"!XL !XL !XL !XL !XL !XL !XL !XL (!3XW)"
Ctl_6:
	.Ascid	"Error status !XW returned from reading !ZL blocks " -
		"starting at LBN !ZL on drive !AS"
Input_Prompt:
	.Ascid	"Please enter shadow set name : "
Retry_Msg_12:
	.Ascid	"Discrepancy detected in LBN range !ZL - !ZL   - retrying ..."



	.Psect	Code,	NoWrt,Exe
	.Entry	Get_Shad, ^M<>

	Calls	#0,	G^Lib$Init_Timer

	Pushaw	Input_Length
	Pushaq	Input_Prompt
	Pushaq	Input_Descr
	Calls	#3,G^Lib$Get_Foreign
	Blbs	R0,	10$
	Ret

10$:	$GetDviW_S -
		DevNam=Input_Descr, -
		ItmLst=Dvi_Item_List, -
		Iosb=Dvi_Iosb
	Blbs	R0,	20$
	Ret

20$:	Movzwl	Dvi_Iosb,	R0
	Blbs	R0,	30$
	Ret

30$:	$GetDviW_S -
		DevNam=Member_Name_Descr, -
		ItmLst=Dvi_Item_List_2, -
		Iosb=Dvi_Iosb
	Blbs	R0,	40$
	Ret

40$:	Movzwl	Dvi_Iosb,	R0
	Blbs	R0,	50$
	Ret


50$:
	Im$Fao_S -
		CtrStr=Ctl_11, -
		P1=#Input_Descr, -
		P2=#0
	Im$Fao_S -
		CtrStr=Ctl_1, -
		P1=#Member_Name_Descr, -
		P2=#Member_Name2_Descr, -
		P3=Disk_Size

60$:
	Divl3	#<Cluster*100>, Disk_Size, Ios_Per_1PerCent
	Incl	Ios_Per_1PerCent		; Round it up just in case.

	Pushal	Efn_1
	Calls	#1,	G^Lib$Get_Ef
	Pushal	Efn_2
	Calls	#1,	G^Lib$Get_Ef

	$Assign_S -
		DevNam=Member_Name_Descr, -
		Chan=Dev_Channel_1
	Blbs	R0,	70$
	Ret

70$:	$Assign_S -
		DevNam=Member_Name2_Descr, -
		Chan=Dev_Channel_2
	Blbs	R0,	80$
	Ret

80$:	Clrl	Read_Block
	Clrl	Eof_Flag
	Clrl	Block_Count
	Movl	Ios_Per_1PerCent,	R10



Read:
	Movl	#6,	Retry_Count
	Addl2	#Cluster,	Block_Count
	Subl3	#1,	Block_Count,	End_Lbn
	Cmpl	Block_Count,	Disk_Size
	Bleq	10$
	Subl2	#Cluster,	Block_Count
	Subl3	Block_Count, Disk_Size, Rec_Buffer_Length

	Bneq	5$
	Brw	Done

5$:	Ashl	#9, Rec_Buffer_Length, Rec_Buffer_Length
	Movl	#1,	Eof_Flag

10$:
	Decl	R10
	Beql	20$
	Brw	30$

20$:
	Movl	Ios_Per_1PerCent,	R10
	Incl	Per_Cent
	Im$Fao_S -
		Ctrstr = Ctl_4, -
		P1=Read_Count, -
		P2=Per_Cent
	
;
;	Queue the first I/O.
;
30$:	$Qio_S	Efn = Efn_1, -
		Chan = Dev_Channel_1, -
		Func = #Io$_ReadLblk, -
		Iosb = Input_Io_Status1, -
		P1 = Rec_Buff_1, -
		P2 = Rec_Buffer_Length, -
		P3 = Read_Count
	Blbs	R0,	110$
	Ret

110$:
;	Im$Fao_S -
;		CtrStr=Ctl_21, -
;		P1=Input_Io_Bytes
;

;
;	Queue the second I/O.
;
	$Qio_S	Efn = Efn_2, -
		Chan = Dev_Channel_2, -
		Func = #Io$_ReadLblk, -
		Iosb = Input_Io_Status2, -
		P1 = Rec_Buff_2, -		; Data buffer address.
		P2 = Rec_Buffer_Length, -	; Data buffer size.
		P3 = Read_Count			; Disk address (LBN).
	Blbs	R0,	130$
	Ret

130$:
	$Synch_S -
		Efn=Efn_1, -
		Iosb=Input_Io_Status1
	Movzwl	Input_Io_Status1,	R0
;	Blbs	R0,	135$
	Blbc	R0,	132$
	Brw	135$

132$:	Im$Fao_S -
		CtrStr=Ctl_6, -
		P1=Input_Io_Status1, -
		P2=Block_Count, -
		P3=Read_Count, -
		P4=#Member_Name_Descr
	Brw	910$


135$:
	$Synch_S -
		Efn=Efn_2, -
		Iosb = Input_Io_Status2
	Movzwl	Input_Io_Status2,	R0
;	Blbs	R0,	140$
	Blbc	R0,	137$
	Brw	140$

137$:	Im$Fao_S -
		CtrStr=Ctl_6, -
		P1=Input_Io_Status2, -
		P2=Block_Count, -
		P3=Read_Count, -
		P4=#Member_Name2_Descr
	Brw	910$


140$:
;
;	Is the data the same on both disks or not ?
;
	Cmpc3	Rec_Buffer_Length, Rec_Buff_1, Rec_Buff_2
	Bneq	200$
	Brw	910$

;
;	Ok, so we've found a discrepancy in a group of <CLUSTER> blocks.  Now
;	we must find out which of those blocks actually has the disrepancy.
;
;
200$:


205$:	Moval	Rec_Buff_1,	R6
	Moval	Rec_Buff_2,	R7

	Movl	Rec_Buffer_Length,	R8
	Ashl	#-9, R8, R8			; R8 = # of blocks to compare.

	Movl	Read_Count,	R9

210$:	Cmpc3	#512,	(R6), (R7)
	Bneq	220$
	Brw	280$

220$:	Im$Fao_S -
		CtrStr=Ctl_3, -
		P1=R9
	Pushl	R6
	Pushl	R7
	Pushl	R10

	Movl	#^X10,	R10
	Clrl	R11

230$:	Cmpc3	#^X20,	(R6),	(R7)
	Bneq	240$
	Brw	250$

240$:	
	Im$Fao_S -
		CtrStr=Ctl_5, -
		P1=28(R6), -
		P2=24(R6), -
		P3=20(R6), -
		P4=16(R6), -
		P5=12(R6), -
		P6=8(R6), -
		P7=4(R6), -
		P8=(R6), -
		P9=R11

	Im$Fao_S -
		CtrStr=Ctl_5, -
		P1=28(R7), -
		P2=24(R7), -
		P3=20(R7), -
		P4=16(R7), -
		P5=12(R7), -
		P6=8(R7), -
		P7=4(R7), -
		P8=(R7), -
		P9=R11

250$:	Addl2	#^X20,	R6
	Addl2	#^X20,	R7
	Addl2	#^X20,	R11
	SobGtr	R10,	260$
	Brw	270$

260$:	Brw	230$


270$:	Popl	R10
	Popl	R7
	Popl	R6

280$:	SobGtr	R8,	290$
	Brw	900$

290$:	Incl	R9
	Addl2	#512,	R6
	Addl2	#512,	R7
	Brw	210$


900$:

	Decl	Retry_Count
	Beql	910$

	Im$Fao_S -
		CtrStr=Retry_Msg_12, -
		P1=Read_Count, -
		P2=End_Lbn
	Pushal	One_Second
	Calls	#1,	G^Lib$Wait
	Brw	30$


910$:	Addl2	#Cluster,	Read_Count

	Tstl	Eof_Flag		; Have we hit EOF ?
	Bneq	Done

	Brw	Read			; go back for more




Done:
	Calls	#0,	G^Lib$Show_Timer

999$:	$Dassgn_S -
		Chan=Dev_Channel
	$Dassgn_S -
		Chan=Dev_Channel_1
	$Dassgn_S -
		Chan=Dev_Channel_2

	Ret

	.End	Get_Shad
