📄 cippd_protocol.c
字号:
* * 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 + -