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

📄 cippd_pmaint.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
     * 2. Retrieve the remote port station address of the target PB.     * 3. Verify the validity of the port station address.     * 4. Attempt to retrieve the PB from the vector of "open PBs".     * 5. Search the formative PB queue for the target PB provided the attempt     *	  made in Step 4 failed.     * 6. Unlock the PCCB provided it was locked within this function.     * 7. Return the PB.     *     * Invalid remote port station addresses trigger event logging of the     * offending packet by the appropriate port driver.  Such logging occurs     * only when:     *     * 1. The remote port station address exceeds the hardware maximum port     *    number for the specified local port.     * 2. The remote port station address is provided to this function in the     *	  form of a buffer( type == BUF ).     *     * In other words, event logging is bypassed whenever the remote port     * station address exceeds the current software( CI PPD ) but not the     * hardware maximum port number of the specified local port; or, the remote     * port station address is explicitly provided to this function(     * type == NO_BUF ).     */    if( !Test_pccb_lock( pccb )) {	Lock_pccb( pccb )	unlock = 1;    }    port = (( type == BUF ) ? ( *pccb->Get_port )( pccb, Scs_to_ppd( scsbp ))			    : ( u_long )*( u_char * )scsbp );    if( port <= ( CIPPD_MAXPATHS - 1 )) {	if(( pb = pccb->Open_pb[ port ] ) == NULL ) {	    for( pb = pccb->Form_pb.flink;		 pb != &pccb->Form_pb &&		  Scaaddr_low( Pb->pinfo.rport_addr ) != port;		 pb = pb->flink ) {}	    if( pb == &pccb->Form_pb ) {		pb = NULL;	    }	}    } else {	pb = NULL;	if( port > pccb->lpinfo.Max_port && type == BUF ) {	    ( void )( *pccb->Log_badportnum )( pccb, Scs_to_ppd( scsbp ));	}    }    if( unlock ) {	Unlock_pccb( pccb )    }    return( Pb );}/*   Name:	cippd_open_pb	- Transition Formative Path Block to Open State * *   Abstract:	This function oversees transitioning of formative paths into *		the PS_OPEN path state.  It is only invoked when SCS receives a *		request for connection establishment on a path that is not *		already open.  It must NEVER be invoked for "open" paths. * *		NOTE: The SCS message buffer passed to this routine must NEVER *		      be consumed by it. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *   pb				- Path Block pointer( OPTIONAL ) *   scsbp			- Address of SCS header in message buffer * *   Outputs: * *   IPL_SCS			- Interrupt processor level * *   Return Values: * *   RET_SUCCESS		- Path is successfully transitioned *   RET_FAILURE		- Path is unsuccessfully transitioned * *   SMP:	The PCCB is locked to further prevent PB deletion and as *		required by both the CI PPD finite state machine and by PD *		routines which close virtual circuits in case such action *		becomes necessary.  PCCBs addresses are always valid because *		these data structures are never deleted once their *		corresponding ports have been initialized. * *		The PB is locked to synchronize access, postpone potential *		deletion, and as required by the CI PPD finite state machine. * *		The PB must EXTERNALLY be prevented from deletion to guarantee *		the validity of its address. */u_longcippd_open_pb( pccb, pb, scsbp )    register PCCB	*pccb;    register PB		*pb;    register SCSH	*scsbp;{    register u_long	status = RET_FAILURE, setcirc = 0;    register GVPPPDH	*cippdbp = Scs_to_ppd( scsbp );    /* The steps involved in transitioning PBs representing formative paths     * into the open state are:     *     * 1. Lock the PCCB.     * 2. Lock the PB.     * 3. Invoke the CI PPD finite state machine to transition the path.     * 4. Unlock the PB.     * 5. Unlock the PCCB.     *     * No attempt is made to transition the formative path in the absence of a     * PB.  This situation occurs when both the path and the attempt to disable     * it fail and the remote system continues to believe the path is "open".     * A STOP CI PPD datagram can NOT be transmitted to notify the remote SYSAP     * of local path failure because no PB exists in order to target datagram     * transmission.  Neither can the finite state machine be invoked to     * disable the path because of PB unavailability.  The only action which     * can and is taken is for this function to make an additional attempt to     * disable the path.     *     * It is possible for SCS sequenced messages to be received over "failed"     * paths because at time of reception it is possible for neither the path     * to have been disabled nor the remote CI PPD to have been notified of     * local path failure.  It is also possible for both actions to have taken     * place or some combinations in between to have occurred.  Failed paths     * require special handling and are processed as follows:     *     * 1. A STOP CI PPD datagram is transmitted to the remote CI PPD.     * 2. The return status is changed from RET_SUCCESS to RET_FAILURE     * 3. The path is disabled.       *     * Step 1 is carried out by the CI PPD finite state machine while Steps 2-3     * are executed by this function following finite state machine invocation.     * Step 2 is required because the finite state machine always returns     * success when processing failed paths and ultimately this routine must     * return a failure status to indicate its inability to open the path.     * Step 3 must also be done by this function instead of by the finite state     * machine.  This is because any PD specific resources associated with the     * PB and reserved for disabling the corresponding path were exhausted     * during the prior path failure processing.  Explicitly disabling the path     * within this function guarantees that at least the attempt is made.     */    Lock_pccb( pccb )    if( pb ) {	Lock_pb( pb )	if( pb->pinfo.state == PS_PATH_FAILURE ) {	    setcirc = 1;	}	status = cippd_dispatch( pccb, pb, CNFE_SCSMSG_REC, cippdbp );	if( pb->pinfo.state == PS_PATH_FAILURE ) {	    status = RET_FAILURE;	}	Unlock_pb( pb )    } else {	setcirc = 1;    }    if( setcirc ) {	( void )( *pccb->Set_circuit )( pccb,					NULL,					( *pccb->Get_port )( pccb, cippdbp ),					SET_VC_CLOSE );    }    Unlock_pccb( pccb )    return( status );}/*   Name:	cippd_remove_pb	- Remove Path Block from System-wide Databases * *   Abstract:	This routine removes and deallocates the PB representing a *		specific failed path from all system-wide databases.  It may be *		invoked only for established paths and only by SCS.  PBs *		representing aborted formative paths are deallocated by *		cippd_clean_fpb() and never through SCS intervention. * *		The SB associated with the path is deallocated following its *		removal from the system-wide configuration database provided *		there are no longer any remaining paths to it. * *		Scheduling of PD specific port re-initialization occurs if *		crash initiated clean up of the local port has completed. * *		NOTE: The appropriate port drivers are always responsible for *		      the removal and deallocation of all free datagram and *		      message buffers associated with failed local ports.  The *		      CI PPD must never attempt to dispose of such buffers. * *   Inputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.fkip	-   0 *   pb				- Path Block pointer *	pinfo.state		-  PS_PATH_FAILURE *	pinfo.nconns		-  0 * *   Outputs: * *   IPL_SCS			- Interrupt processor level *   pccb			- Port Command and Control Block pointer *	forkb			-  PCCB fork block *	lpinfo.ppd.cippd	-  CI PPD specific local port information *	    npaths		-   Number of paths associated with the port *	ppd.cippd		-  CI PPD specific PCCB fields *	    fsmstatus.fkip	-   Fork operation in progress *   sb				- System Block pointer *	sinfo.npaths		-  Number of paths to system * *   SMP:	The SCA database is locked( EXTERNALLY ) for PB removal from *		the system-wide configuration database, for SB removal from *		this database if it becomes necessary, and to guarantee the *		validity of the PB address on entry to this routine. * *		The PCCB is locked to allow exclusive access to PCCB contents. *		PCCB addresses are always valid because these data structures *		are never deleted once their corresponding ports have been *		initialized. * *		The PB is locked to synchronize access, for removal from all *		system-wide databases, for deallocation, and as required by PD *		routines which optionally deallocate emergency command packets *		associated with the PB.  PB locks are released immediately *		prior to PB deallocation as required by scs_dealloc_pb(). *		PB address validity is guaranteed both by single threading of *		path clean up and by incrementing the PB semaphore prior *		to scheduling of asynchronous PB clean up.  The former should *		be sufficient to guarantee validity, but the latter is done *		anyway as additional protection and to detect errors in error *		recovery logic. * *		The PB semaphore is decremented following PB locking.  It was *		originally incremented prior to scheduling of asynchronous path *		clean up to act as a further guarantee of PB validity and to *		detect errors in error recovery logic when clean up eventually *		commenced. */voidcippd_remove_pb( pccb, pb )    register PCCB	*pccb;    register PB		*pb;{    register GVPH	*cibp;    register SB		*sb = pb->sb;    register u_long	( *dealloc )();    /* Removing the PB from the system-wide databases includes:     *     *  1. Locking the PCCB.     *  2. Locking the PB.     *  3. Decrementing the PB semaphore.     *  4. Optionally removing and deallocating all PD emergency command     *	   packets still associated with the PB.     *  5. Removing the PB from all internal queues.     *  6. Unlocking the PB.     *  7. Deallocating the PB.     *  8. Decrementing the count of paths associated with the appropriate SB,     *	   and removing the SB from all queues and deallocating it when there     *     are no longer any paths to the system.     *  9. Decrementing the number of paths originating at the port and     *     scheduling port initialization through forking only when there are     *     no longer any paths originating at the port and port clean up is     *	   currently in progress.     * 10. Unlock the PCCB.     *     * The PB semaphore is decremented( Step 3 ) because it was incremented by     * the CI PPD finite state machine prior to asynchronous scheduling of PB     * clean up to act as a further guarantee of PB validity when clean up( by     * cippd_clean_pb() ) eventually commenced and to detect errors in error     * recovery logic.     *     * The PCCB fork block is used to schedule port initialization( Step 8 ).     * It should always be available because it is used only for port clean up     * and initialization, these activities are single threaded, and     * initialization always follows clean up.  Guaranteed availability of the     * PCCB fork block is one of the benefits of single threading of port clean     * up and initialization.     *     * Once PB removal and deallocation completes, the CI PPD is free to     * attempt establishment of a new path incarnation.  Such attempts do not     * occur until after the path is re-discovered through polling.  New path     * incarnations are fully subject to crashing on encountering of     * sufficiently serious errors.     */    Lock_pccb( pccb )    Lock_pb( pb )    Decr_pb_sem( pb )    if( Test_pb_sem( pb )) {	( void )panic( PPDPANIC_BPATH );    }    if(( dealloc = pccb->Dealloc_buf )) {	( void )( *dealloc )( pb );    }    Remove_entry( pb->flink )    pccb->Open_pb[ Scaaddr_low( pb->pinfo.rport_addr )] = NULL;    Unlock_pb( pb )    ( void )scs_dealloc_pb( pccb, pb );    if(( --sb->sinfo.npaths ) == 0 ) {	Remove_entry( sb->flink )	( void )scs_dealloc_sb( sb );    }    if( --pccb->lpinfo.Npaths == 0 &&	 pccb->Fsmstatus.cleanup   &&	 pccb->lpinfo.Nform_paths == 0 ) {	Pccb_fork( pccb, pccb->Init_port, PPDPANIC_PCCBFB )    }    Unlock_pccb( pccb )}

⌨️ 快捷键说明

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