⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cippd_protocol.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
 * *		The PCCB is locked( EXTERNALLY ) allowing exclusive access to *		PCCB contents, postponing premature PB deletion, and as *		required by cippd_log_path() and cippd_csyslev() in case event *		logging becomes necessary. * *		The PB is locked( EXTERNALLY ) postponing potential deletion *		and allowing exclusive access to PB contents. * *		The PB semaphore is incremented whenever it is found necessary *		to unlock the PB and yet postpone potential PB deletion.  This *		need exists during both locking of the SCA database and SCS *		notification of new path existence.  The PB semaphore is *		decremented once the PB is again protected against premature *		deletion by the re-obtaining of its lock. */u_longcippd_enter_db( pccb, pb, cippdbp )    register PCCB	*pccb;    register PB		*pb;    GVPPPDH		*cippdbp;{    register sbq	*sb;    register SB		*target_sb = pb->sb;    register u_long	nstatus, sstatus;    u_long		old_pstate, lock_scadb = 0, status = RET_SUCCESS,			portnum = Scaaddr_low( pb->pinfo.rport_addr );    /* Lock the SCA database if it is not EXTERNALLY locked and search for the     * target system within the system-wide configuration database.  This     * search terminates when one of the following conditions is met:     *     * 1. The target system is NOT found within the database.     * 2. The target system is found within the database.     * 3. A system is found within the database which matches the target system     *    but possesses a different incarnation number.     * 4. A system with the same system identification number as the target     *	  system but with a different node name is found within the database.     * 5. A system with the same node name as the target system but with a     *	  different system identification number is found within the database.     *     * The occurrence of any one of the last three conditions signals a     * system-wide configuration database conflict and the following actions     * are taken:     *     * 1. The SCA database is unlocked but only if it was locked INTERNALLY.     * 2. The database conflict is logged.     * 3. A failure status is returned to trigger path clean up, including path     *    disablement by the finite state machine.     *     * Only the very first database conflict involving a specific remote port     * is logged( Action 2 ).  Logging of subsequent conflicts is bypassed     * until after the CI PPD determines that a conflict with the specific     * remote port no longer exists.  Note that the conflict is designated as     * being associated with a specific remote port instead of with a specific     * remote system as would normally be expected.  This is because such     * conflicts can not be treated as common system level events because the     * identity of the remote system is itself in question.     *     * Once it has been determined that a system-wide configuration database     * conflict does not exist, the remote CI PPD protocol version level is     * checked for a mismatch.  Two types of mismatches are possible:     *     * 1. The remote CI PPD is running a later version of the protocol.     * 2. The remote CI PPD is running an earlier version of the protocol.     *     * Any mismatch is logged as a common system level event.  Such events are     * associated with specific remote systems and not with specific ports on     * those systems.  Only the very first instance of each mismatch type     * involving a specific remote system is logged.  Logging of subsequent     * mismatches of that type are bypassed until after the CI PPD determines     * that the specific mismatch with the remote system no longer exists.     *     * Mismatches with the remote CI PPD running a later version of the CI PPD     * protocol are considered benign.  The local CI PPD always attempts to     * "talk up" to the remote CI PPD.  This is not the case when a remote CI     * PPD is found to be running an earlier CI PPD protocol version.  The     * local CI PPD never attempts to "talk down" to a remote CI PPD.  Instead,     * the SCA database is unlocked( if it was locked INTERNALLY ) and a     * failure status is returned to trigger path clean up, including path     * disablement by the finite state machine, after the mismatch is logged.     *     * If no database conflict is found and if no serious CI PPD protocol     * mismatch exists, then this function proceeds to enter the PB     * representing the formative path into the system-wide databases as     * follows:     *     *  1. The formative SB is inserted into the system-wide configuration     *     database if the target system was not located; otherwise, the PB's     *	   SB pointer is updated to the target system's SB and the formative SB     *	   is dispossed of.     *  2. The PB is removed from the appropriate port's formative PB queue.     *  3. The PB is inserted into the system-wide configuration database.     *  4. The bits representing the remote port within the database conflict     *	   and path establishment timeout log maps are cleared.     *  5. The PB address is cached in the PCCB PS_OPEN PB vector table by its     *	   remote port address.     *  6. Existence of the new path is event logged.     *  7. The remote system software type is verified.     *  8. The SCA database is unlocked but only if it was unlocked INTERNALLY.     *  9. SCS is notified of the existence of a new path to the system.     * 10. A status of success is returned.     *     * Verification of the remote system software type( Step 7 ) is necessary     * because paths may be established to remote systems running other than     * the following supported software types:     *     * 1. U-32( Ultrix systems ).     * 2. HSC( HSC storage controllers ).     * 3. RFXX( DSSI disk storage controllers ).     * 4. TFXX( DSSI tape storage controllers ).     *     * Nothing is done to prevent the establishment of paths to remote systems     * running unsupported software types.  However, the discovery of such a     * system is logged as a common system level event both to inform the     * customer that he/she is violating the SPD and to record the violation     * for our benefit in case some problem occurs laters on.  Only the very     * first instance of an unsupported software type associated with a     * specific remote system is logged.  Logging of subsequent violations is     * bypassed until after the CI PPD ascertains that the remote system is     * running a supported software type.     *     * The path's state is transitioned to "open" prior to event logging( Step     * 6 ) and notifying SCS( Step 9 ) of the new path to the system.  This     * allows SYSAPs so notified to immediately request logical SCS connections     * across the newly established path.     *     * There are two instances when this function must temporarily release all     * locks.  These are:     *     * 1. When locking the SCA database.     * 2. When notifying SCS of new path existence.     *     * All locks must be released prior to locking the SCA database in order to     * preserve the SCA locking hierarchy.  They must be released during SCS     * notification of new path existence both to allow SCS to process the     * event and because it is required by the SCA architecture.  In both     * instances the PB must be prevented from being cleaned up and deallocated     * while locks are released.  The mechanism chosen to provide this     * protection is incrementing of the appropriate PB semaphore.     *     * Incrementing a PB semaphore protects the corresponding PB against clean     * up and deallocation because routines charged with these tasks are not     * allowed to perform them while the semaphore is incremented.  This     * restriction is taken advantage of by this routine whenever it wishes     * to protect its PBs as follows:     *     * 1. Prior to releasing all locks the appropriate PB semaphore is     *	  incremented.     * 2. The PCCB and PB locks are released.     * 3. The SCS database is locked or SCS is notified of new path existence.     * 4. The PCCB is locked.     * 5. The PB is retrieved.     * 6. The PB is locked.     * 7. The PB semaphore is decremented.     *     * Whenever all locks are released, it allows another CI PPD thread to     * obtain them, fail the corresponding path, and schedule asynchronous PB     * clean up.  However, the thread which becomes responsible for PB clean up     * and deallocation is prevented from doing so while the PB semaphore is     * incremented.  This allows the current thread to re-obtain all locks(     * Steps 4 and 6 ), decrement the PB semaphore( Step 7 ) and exit this     * function.  Only when the current thread releases its re-obtained PB lock     * can the thread responsible for PB clean up and deallocation perform     * these tasks.  This is how protection of the PB is achieved through     * incrementing of its semaphore.     *     * The PB is retrieved before re-locking( Step 5 ) whenever locks are     * temporarily released.  This retrieval is actually unnecessary because     * incrementing the PB semaphore should protect the validity of cached PB     * addresses as it protects the PB themselves from clean up and     * deallocation.  It is done anyway as a further precaution and to detect     * the existence of errors in error recovery logic.  Cached PCCB addresses     * remain valid because PCCBs are never deleted once their ports have been     * initialized.     *     * While this routine can protect its PBs from clean up and deallocation it     * can NOT protect them from path state changes while it has temporarily     * released all locks.  This allows the following path state changes to     * possibly occur when locks are released:     *     * 1. Paths can be opened by other CI PPD threads when locks are released     *	  for the purpose of locking the SCA database.     * 2. Paths may also fail, but not be cleaned up, whenever locks are     *	  temporarily released as documented above.     *     * Opening a PB involves entering it into the system-wide databases.     * Therefore, occurrence of the first type of path state change means that     * the current CI PPD thread no longer has any need to execute this action     * and may immediately return success.  Path failures while locks are     * temporarily released present an entirely different matter because the     * paths can no longer be successfully entered into the system-wide     * databases.  Such a path state change is handled by immediately returning     * a failure status to indicate this inability.  This does forces iterative     * invocation of the CI PPD finite state machine to terminate the target     * path( event == CNFE_PROC_ERROR ).  However, as the path has failed and     * is already undergoing error recovery the iterative invocation is just     * dismissed without further action being taken.     *     * NOTE: This function must determine whether to return success or failure     *	     before inserting the PB into the system-wide databases.  This is     *	     because the act of inserting the PB establishes the path fully and     *	     no action function can return a failure status for a fully     *	     established path( see rule 4 at front of module ).     *     * NOTE: Optional information logged for database conflicts includes the     *	     station address of a remote port located on the known system.  The     *	     known system may have many such remote ports.  Only the station     *	     address of the first remote port known locally is logged.     */    if( !Test_scadb_lock()) {	old_pstate = pb->pinfo.state;	Incr_pb_sem( pb )	Unlock_pb( pb )	Unlock_pccb( pccb )	Lock_scadb()	Lock_pccb( pccb )	if(( pb = cippd_get_pb( pccb, ( SCSH * )&portnum, NO_BUF )) == NULL ) {	    ( void )panic( PPDPANIC_NOPATH );	}	Lock_pb( pb )	Decr_pb_sem( pb )	if( old_pstate != pb->pinfo.state ) {	    if( pb->pinfo.state == PS_OPEN ||		 pb->pinfo.state == PS_PATH_FAILURE ){		Unlock_scadb()		if( pb->pinfo.state == PS_PATH_FAILURE ) {		    status = RET_FAILURE;		}		return( status );	    } else {		( void )panic( PPDPANIC_PSTATE );	    }	}    } else {	lock_scadb = 1;    }    for( sb = scs_config_db.flink; sb != &scs_config_db; sb = sb->flink ) {	nstatus = Comp_node( target_sb->sinfo.node_name, Sb->sinfo.node_name );	sstatus = Comp_scaaddr( target_sb->sinfo.sysid, Sb->sinfo.sysid );	if( sstatus  &&	     nstatus &&	     Comp_quad( Sb->sinfo.swincrn, target_sb->sinfo.swincrn )) {	    break;	} else if( !sstatus && !nstatus ) {	    continue;	} else {	    Move_quad( target_sb->sinfo.swincrn,		       pccb->Elogopt.dbcoll.cippd_rswincrn[ 0 ])	    Move_quad( Sb->sinfo.swincrn,		       pccb->Elogopt.dbcoll.cippd_kswincrn[ 0 ])	    Move_scaaddr( Sb->sinfo.sysid,			  *pccb->Elogopt.dbcoll.cippd_ksysid )	    Move_node( Sb->sinfo.node_name,		       pccb->Elogopt.dbcoll.cippd_kname )	    Move_scaaddr((( PB * )Sb->pbs.flink )->pinfo.rport_addr,			  *pccb->Elogopt.dbcoll.cippd_krsaddr )	    Move_scaaddr(((( PB * )Sb->pbs.flink )->pccb )->lpinfo.addr,			  *pccb->Elogopt.dbcoll.cippd_klsaddr )	    if( !lock_scadb ) {		Unlock_scadb()	    }	    if( !Test_lpinfomap( Dbclogmap, portnum )) {		Set_lpinfomap( Dbclogmap, portnum )		( void )cippd_log_path( pccb, pb, NULL, RE_DBCONFLICT );	    }	    status = RET_FAILURE;	    break;	}    }    if( status == RET_SUCCESS ) {	if( pb->pinfo.protocol == pccb->lpinfo.Protocol ) {	    ( void )cippd_csyslev( pccb, pb->sb, W_TALKUP, CLEAR );	    ( void )cippd_csyslev( pccb, pb->sb, E_TALKDOWN, CLEAR );	} else {	    pccb->Elogopt.protocol.cippd_remote = pb->pinfo.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -