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

📄 nsrec.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	}	alarm(0);	LOG2(L_COMM,"(%5d) recovery: ready to decide\n",Logstamp);	for (np=Nsinfo; np < &Nsinfo[MAXNS]; np++) {		switch (np->n_state) {		case R_PRIME:			if (pnp != NULL) {				PLOG3("RFS name server: WARNING: found 2 name servers, %s and %s\n",					pnp->n_dname, np->n_dname);				PLOG2("RFS name server: Using %s as primary\n",					pnp->n_dname);				break;			}			pnp = np;			LOG3(L_COMM,"(%5d) recovery: state of %s is R_PRIME\n",				Logstamp, np->n_dname);			break;		case R_NOTPRIME:			LOG4(L_COMM,"(%5d) recovery: state of %s is %s R_NOTPRIME\n",				Logstamp, np->n_dname, (npnp)?"":"first");			if (!npnp)				npnp = np;			break;		case R_UNK:			LOG3(L_COMM,"(%d) recovery: no resp from connected ns %s\n",				Logstamp, np->n_dname);			np->n_state = R_DEAD;			/* fall through to clean up port	*/		case R_DEAD:		case R_PENDING:			LOG4(L_COMM,"(%5d) recovery state of %s is %s\n",				Logstamp, np->n_dname, (np->n_state == R_DEAD)?				"R_DEAD":"R_PENDING, set to R_DEAD");			np->n_state = R_DEAD;			if (np->n_pd != -1) {				nsrclose(np->n_pd);				np->n_pd = -1;			}			break;		}	}	if (!pnp && !(pnp = npnp))  {		PLOG1("RFS name server: recovery: no primary assignment possible\n");		sigset(SIGUSR2,usr2sig);		return(RFS_FAILURE);	}	pnp->n_state = R_PRIME;	if (Mynp == pnp) {		LOG2(L_ALL,"(%5d) recovery: becoming PRIMARY\n",			Logstamp);			Primary = TRUE;	}	else {		LOG3(L_ALL,"(%5d) recovery: using %s as PRIMARY\n",			Logstamp, pnp->n_dname);	}	if (Primary)	/* tell the world	*/		for (np=Nsinfo; np < &Nsinfo[MAXNS]; np++)			if (np->n_state == R_NOTPRIME)				r_sndreq(np->n_pd, np, QUERY, NS_IM_P);	/* now re-set sigsets for polling and do any initialization.	*/	if (!Primary) {		sigset(SIGALRM,r_poll);		Alarmsig = (void (*)()) r_poll;	}	else {		sigset(SIGALRM,r_checkup);		Alarmsig = (void (*)()) r_checkup;	}	alarm((timesave)?timesave:Polltime);	sigset(SIGUSR2,usr2sig);	return(RFS_SUCCESS);}intr_sndreq(pd, np, flags, opcode)int	pd;struct ns_info	*np;int	flags;int	opcode;{	char	*block=NULL;	static int	size=0;	static struct header	Head;	static struct request	Req;	Req.rq_head = &Head;	Head.h_version = NSVERSION;	Head.h_flags = flags;	Head.h_opcode = opcode;	Head.h_dname = Dname;	LOG6(L_COMM,"(%5d) r_sndreq: send %s %s to machine %s on pd %d\n",		Logstamp, fntype(opcode), (flags&QUERY)?"query":"response",		np->n_dname, pd);	if ((block = reqtob(&Req, block, &size)) == NULL) {		LOG3(L_ALL,"(%5d) recovery reqtob 2 failed, ns=%s\n",			Logstamp,np->n_dname);		return(RFS_FAILURE);	}	if (nswrite(pd,block,size) == -1) {	    LOG3(L_ALL,"(%5d) recovery: can't reply IM_NP to %s\n",		Logstamp,np->n_dname);		np->n_state = R_DEAD;		free(block);		return(RFS_FAILURE);	}	free(block);	return(RFS_SUCCESS);}struct ns_info *pdtonp(pd)int	pd;{	register struct ns_info	*np = &Nsinfo[0];	register struct ns_info	*ep = &Nsinfo[MAXNS];	if (pd == -1)		return(NULL);	while (np < ep) {		if (np->n_pd == pd && np->n_state != R_UNUSED)			return(np);		np++;	}	return(NULL);}/* * check a port descriptor, pd, before it is closed and clean up * any ns_info structure associated with it. */intnp_clean(pd)int	pd;{	struct ns_info	*np;	if ((np = pdtonp(pd)) != NULL) {		np->n_pd = -1;		np->n_state = R_DEAD;	}	return;}voidrst_alrm(){	alarm(0);	Rdone = TRUE;}struct ns_info *nmtonp(name)char	*name;{	register struct ns_info	*np = &Nsinfo[0];	register struct ns_info	*ep = &Nsinfo[MAXNS];	if (name == NULL)		return(NULL);	while (np < ep) {		if (np->n_state != R_UNUSED &&		    strcmp(name,np->n_dname) == NULL)			return(np);		np++;	}	return(NULL);}checkver(req)struct request	*req;{	if (req->rq_head->h_version > NSVERSION) {		LOG4(L_ALL,"(%5d) checkver: version mismatch, reqver %d, nsver %d\n",			Logstamp, req->rq_head->h_version, NSVERSION);		return(RFS_FAILURE);	}	return(RFS_SUCCESS);}intnsrecover(pd,type)int	pd;int	type;{	struct ns_info	*np;	LOG2(L_COMM,"(%5d) nsrecover: enter\n",Logstamp);	np = pdtonp(pd);	switch(type) {	case REC_CON: /* wait for poll message	*/		break;	case REC_ACC: /* got reply to checkup connection, send poll.	*/		if (r_sndreq(pd, np, QUERY, (Primary)?NS_IM_P:NS_IM_NP) == RFS_FAILURE) {			nsrclose(pd);			np->n_state = R_DEAD;			np->n_pd = -1;		}		else			np->n_state = R_UNK;		break;	case REC_HUP:		nsrclose(pd);		if (np) {			np->n_pd = -1;			if (np->n_state == R_PRIME)				return(setrstate());			np->n_state = R_DEAD;		}		break;	}	return(RFS_SUCCESS);}/* * check an incoming request of type NS_IM_P or NS_IM_NP for * basic sanity.  I.e., make sure there are no conflicts with * what is known about the machine already. */intr_sane(req,pd)struct request	*req;int		pd;{	struct ns_info	*np;	struct header	*hp = req->rq_head;	if ((np = nmtonp(hp->h_dname)) == NULL) {		LOG3(L_ALL,"RFS name server: rcvd %s msg from unk NS %s\n",			getctype(hp->h_opcode),hp->h_dname);		/* return success since we don't want to stop here */		nsrclose(pd);		return(RFS_SUCCESS);	}	if (np->n_pd == -1)		np->n_pd = pd;	switch (hp->h_opcode) {	case NS_IM_P:		if (Primary) {			PLOG2("RFS name server: NS %s, primary collision\n",				hp->h_dname);			/* yield if other machine is higher on list */			if (nmtonp(Dname) > np)		    		return(setrstate());			/* otherwise tell it who's boss	*/			if (r_sndreq(pd, np, QUERY, NS_IM_P) == RFS_FAILURE) {				nsrclose(pd);				np->n_state = R_DEAD;				np->n_pd = -1;		    		return(setrstate());			}		    	return(RFS_SUCCESS);		}		if (np->n_state != R_PRIME) {			LOG3(L_ALL,"(%5d): found possible second primary %s\n",				Logstamp, hp->h_dname);			return(setrstate());		}		break;	case NS_IM_NP:		switch (np->n_state) {			case R_UNK:			case R_DEAD:				np->n_state = R_NOTPRIME;				break;			case R_NOTPRIME:				break;			default:				LOG3(L_ALL,"(%5d) %s changing state to NS_IM_NP\n",					Logstamp,hp->h_dname);				return(setrstate());		}		break;	}	return(RFS_SUCCESS);}/* * periodic polling routine for primary machine. */intr_checkup(){	register struct ns_info	*np = &Nsinfo[0];	register struct ns_info	*ep = &Nsinfo[MAXNS];	void	(*usr2sig)();	usr2sig = sigset(SIGUSR2,SIG_HOLD);	sigset(SIGALRM,SIG_IGN);	alarm(0);	for (; np < ep; np++) {		if (np->n_state == R_UNUSED)			continue;		if (strcmp(Dname,np->n_dname) == 0)			continue;		if (np->n_pd == -1) {			if ((np->n_pd = rconnect(np->n_addr,RECOVER)) == -1)				np->n_state = R_DEAD;			else				np->n_state = R_PENDING;		}		else if (r_sndreq(np->n_pd, np, QUERY,(Primary)?NS_IM_P:NS_IM_NP)				== RFS_FAILURE) {			np->n_state = R_DEAD;			nsrclose(np->n_pd);			np->n_pd = -1;		}	}	sigset(SIGALRM,r_checkup);	alarm(Polltime);	sigset(SIGUSR2,usr2sig);	return;}/* * periodic polling routine for secondary machine. */intr_poll(){	int	i;	int	pd;	char	qbuf[BUFSIZ];	char	*block = NULL;	int	size = 0;	void	(*usr2sig)();	static struct header	Head;	static struct request	Req;	static struct question	Question;	struct question		*qp = &Question;	LOG2(L_COMM,"(%5d) r_poll: enter\n",Logstamp);	usr2sig = sigset(SIGUSR2,SIG_HOLD);	sigset(SIGALRM,SIG_IGN);	alarm(0);	if ((pd = primepd()) == -1) {		if (setrstate() == RFS_FAILURE) 			Done = TRUE;		/* don't reset SIGALRM, setrstate will do that	*/		sigset(SIGUSR2,usr2sig);		return;	}	LOG2(L_COMM,"(%5d) r_poll: polling primary\n",Logstamp);	Req.rq_head = &Head;	Head.h_version = NSVERSION;	Head.h_flags = QUERY;	Head.h_opcode = NS_QUERY;	Head.h_dname = Dname;	Head.h_qdcnt = 1;	Req.rq_qd = &qp;	Question.q_name = qbuf;	Question.q_type = ANYTYPE;	for (i=0; i < Mylastdom; i++) {#ifdef RIGHT_TO_LEFT		sprintf(qbuf,"%c%c%s",WILDCARD,SEPARATOR,Mydomains[i]);#else		sprintf(qbuf,"%s%c%c",Mydomains[i],SEPARATOR,WILDCARD);#endif		LOG3(L_COMM,"(%5d) r_poll: poll primary for domain %s\n",			Logstamp, Mydomains[i]);		if ((block = reqtob(&Req,block,&size)) == NULL) {			LOG3(L_ALL,"(%5d) r_poll: reqtob failed domain = %s\n",				Logstamp, Mydomains[i]);			continue;		}		if (nswrite(pd,block,size) == -1) {			LOG2(L_ALL,"(%5d) r_poll: write to primary failed\n",				Logstamp);			free(block);			if (setrstate() == RFS_FAILURE)				Done = TRUE;			/* don't reset SIGALRM, setrstate will do that	*/			sigset(SIGUSR2,usr2sig);			return;		}		free(block);		block = NULL;	}	sigset(SIGALRM,r_poll);	alarm(Polltime);	sigset(SIGUSR2,usr2sig);	return;}intprimepd(){	register struct ns_info	*np = &Nsinfo[0];	register struct ns_info *ep = &Nsinfo[MAXNS];	while (np < ep) {		if (np->n_state == R_PRIME)			return(np->n_pd);		np++;	}	return(-1);}/* * add data collected by poll to database */intnsdata(req)struct request	*req;{	long	i;	char	fname[BUFSIZ];	char	dname[BUFSIZ];	struct header	*hp;	LOG2(L_COMM,"(%5d) nsdata: enter\n",Logstamp);	hp = req->rq_head;	if (hp->h_rcode != R_NOERR || hp->h_qdcnt <= 0) {		LOG4(L_ALL,"(%5d) nsdata: rcode %d or qdcnt %d bad\n",			Logstamp, hp->h_rcode, hp->h_qdcnt);		return(R_NSFAIL);	}	if (!(hp->h_flags & AUTHORITY)) {		if (setrstate() == RFS_FAILURE) {			Done = TRUE;			return(R_NSFAIL);		}		return(R_NOERR);	}	strcpy(dname,dompart(req->rq_qd[0]->q_name));	LOG3(L_COMM,"(%5d) nsdata: reply for domain %s\n",		Logstamp,dname);	if (!mydom(dname)) {		LOG3(L_ALL,"(%5d) nsdata: reply rcvd for un-owned domain %s\n",			Logstamp,dname);		return(R_NSFAIL);	}	cleardom(dname);	for (i=0; i < hp->h_ancnt; i++) {#ifdef RIGHT_TO_LEFT		sprintf(fname,"%s%c%s",req->rq_an[i]->rr_name,SEPARATOR,dname);#else		sprintf(fname,"%s%c%s",dname,SEPARATOR,req->rq_an[i]->rr_name);#endif		LOG4(L_COMM,"(%5d) nsdata: addrr %s, %s\n",			Logstamp,fname,prec(req->rq_an[i]));		addrr(fname,req->rq_an[i]);	}	return(R_NOERR);}/* * ns_rel handles rfadmin -p.  if the request is local, it sends * a copy of its current database to the secondaries and goes into * recovery, sending NS_RELs to each secondary.  If the request * is remote, it should be from the primary, and signals the need * to go into recovery to get a new primary. */intns_rel(pd)int	pd;{	struct res_rec	**rlist;	struct request	*req;	struct header	*hp;	struct request	*nreq;	int		ret;	int		i;	char		*key=NULL;	struct request	*newreq();	struct request	*nsfunc();	struct ns_info	*np;	struct nsport	*pptr = pdtoptr(pd);	if (!pptr)		return(R_FAIL);	switch(pptr->p_mode) {	case LOCAL:		/* this is the primary side of rfadmin -p	*/		if (!Primary)			return(R_PERM);		break;	case RECOVER:		/* this is the secondary side of rfadmin -p	*/		if ((np=pdtonp(pd)) == NULL)			return(R_FAIL);		if (Primary || np->n_state != R_PRIME)			return(R_PERM);		/* now "remove" primary from recovery algorithm	*/		np->n_state = R_UNUSED;		remfrsel(pptr);		if (setrstate() == RFS_FAILURE) {			PLOG1("RFS name server: FATAL recovery error\n");			Done = TRUE;			return(R_NSFAIL);		}		addtosel(pptr);		np->n_state = R_UNK;		return(R_NOERR);	default:		return(R_FORMAT);	}	/* at this point we have legitimate local requests only	*/	if ((req = newreq(NS_QUERY,QUERY,Dname)) == NULL)		return(R_NSFAIL);	if ((key = malloc(MAXDNAME)) == NULL ||	   (req->rq_qd=(struct question **)malloc(sizeof(struct question *))) == NULL||	   (req->rq_qd[0]=(struct question *)malloc(sizeof(struct question))) == NULL){		if (key)			free(key);		freerp(req);		return(R_NSFAIL);	}	hp = req->rq_head;	hp->h_qdcnt = 1;	req->rq_qd[0]->q_name = key;	req->rq_qd[0]->q_type = ANYTYPE;	for (i=0; i < Mylastdom; i++) {		sprintf(key,"%s.%c",Mydomains[i],WILDCARD);		if ((nreq = nsfunc(req,-1)) == NULL) {			freerp(req);			return(R_NSFAIL);		}		if (nspass(nreq) == RFS_FAILURE) {			freerp(req);			freerp(nreq);			return(R_NSFAIL);		}		freerp(nreq);	}	freerp(req);	ret = nsrel();	return(ret);}intnspass(nreq)struct request	*nreq;{	char	*block = NULL;	int	size = 0;	int	i;	struct ns_info	*np;	struct header	*hp = nreq->rq_head;	LOG2(L_ALL,"(%5d) nsrel: relinquish primary status\n",Logstamp);	if ((block = reqtob(nreq,block,&size)) == NULL) {		LOG2(L_ALL,"(%5d) nsrel: reqtob failed\n",Logstamp);		return(RFS_FAILURE);	}	for (i=0, np = Nsinfo; i < MAXNS; i++, np++)		if (np->n_state == R_NOTPRIME)			nswrite(np->n_pd,block,size);	free(block);	return(RFS_SUCCESS);}intnsrel(){	int	i;	int	polled = 0;	struct ns_info	*np;	struct nsport	*pptr;	for (i=0, np = Nsinfo; i < MAXNS; i++, np++)		if (np->n_state == R_NOTPRIME && strcmp(Dname,np->n_dname)) {			if (r_sndreq(np->n_pd, np, QUERY, NS_REL) == RFS_FAILURE) {				nsrclose(np->n_pd);				np->n_pd = -1;				np->n_state = R_DEAD;			}			else				polled++;		}	if (polled == 0) {		LOG2(L_ALL,"(%5d) nsrel: can't pass control, no secondaries\n",			Logstamp);		return(R_NONAME);	}	alarm(0);	sigrelse(SIGALRM);	sleep(R_TIMEOUT+5);	for (i=0, np = Nsinfo; i < MAXNS; i++, np++)		if (np->n_state == R_NOTPRIME && strcmp(Dname,np->n_dname)) {			pptr = pdtoptr(np->n_pd);			if (ioctl(pptr->p_fd,I_FLUSH,FLUSHR) == -1) {				nsrclose(np->n_pd);				np->n_pd = -1;				np->n_state = R_DEAD;			}		}	if (setrstate() == RFS_FAILURE) {		PLOG1("RFS name server: FATAL error, nsrel recovery failure\n");		Done = TRUE;		return(R_NSFAIL);	}	/* make sure we still aren't primary	*/	if (Primary)		return(R_NONAME);	return(R_NOERR);}

⌨️ 快捷键说明

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