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

📄 master.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			timevalsub(&stop, &stop, &check);			if (stop.tv_sec >= 1) {				if (trace)					(void)fflush(fd);				/*				 * ack messages periodically				 */				wait.tv_sec = 0;				wait.tv_usec = 0;				if (0 != readmsg(TSP_TRACEON,ANYADDR,						 &wait,0))					traceon();				(void)gettimeofday(&check, 0);			}		}#ifdef sgi		if (pri >= 0)			(void)schedctl(NDPRI,0,pri);#endif /* sgi */		if (trace)			fprintf(fd, "measurements finished at %s\n", date());	}	if (!(status & SLAVE)) {		if (!dictate) {			mydelta = networkdelta();		} else {			dictate--;		}	}	if (trace && (mydelta != 0 || (status & SLAVE)))		fprintf(fd,"local correction of %ld ms.\n", mydelta);	correct(mydelta);}/* * sends the time to each slave after the master * has received the command to set the network time */voidspreadtime(){	struct hosttbl *htp;	struct tsp to;	struct tsp *answer;/* Do not listen to the consensus after forcing the time.  This is because *	the consensus takes a while to reach the time we are dictating. */	dictate = 2;	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {		to.tsp_type = TSP_SETTIME;		(void)strcpy(to.tsp_name, hostname);		(void)gettimeofday(&to.tsp_time, 0);		answer = acksend(&to, &htp->addr, htp->name,				 TSP_ACK, 0, htp->noanswer);		if (answer == 0) {			/* We client does not respond, then we have			 * just wasted lots of time on it.			 */			syslog(LOG_WARNING,			       "no reply to SETTIME from %s", htp->name);			if (++htp->noanswer >= LOSTHOST) {				if (trace) {					fprintf(fd,					     "purging %s for not answering",						htp->name);					(void)fflush(fd);				}				htp = remmach(htp);			}		}	}}voidprthp(delta)	clock_t delta;{	static time_t next_time;	time_t this_time;	struct tms tm;	struct hosttbl *htp;	int length, l;	int i;	if (!fd)			/* quit if tracing already off */		return;	this_time = times(&tm);	if (this_time + delta < next_time)		return;	next_time = this_time + CLK_TCK;	fprintf(fd, "host table: %d entries at %s\n", slvcount, date());	htp = self.l_fwd;	length = 1;	for (i = 1; i <= slvcount; i++, htp = htp->l_fwd) {		l = strlen(htp->name) + 1;		if (length+l >= 80) {			fprintf(fd, "\n");			length = 0;		}		length += l;		fprintf(fd, " %s", htp->name);	}	fprintf(fd, "\n");}static struct hosttbl *newhost_hash;static struct hosttbl *lasthfree = &hosttbl[0];struct hosttbl *			/* answer or 0 */findhost(name)	char *name;{	int i, j;	struct hosttbl *htp;	char *p;	j= 0;	for (p = name, i = 0; i < 8 && *p != '\0'; i++, p++)		j = (j << 2) ^ *p;	newhost_hash = &hosttbl[j % NHOSTS];	htp = newhost_hash;	if (htp->name[0] == '\0')		return(0);	do {		if (!strcmp(name, htp->name))			return(htp);		htp = htp->h_fwd;	} while (htp != newhost_hash);	return(0);}/* * add a host to the list of controlled machines if not already there */struct hosttbl *addmach(name, addr, ntp)	char *name;	struct sockaddr_in *addr;	struct netinfo *ntp;{	struct hosttbl *ret, *p, *b, *f;	ret = findhost(name);	if (ret == 0) {		if (slvcount >= NHOSTS) {			if (trace) {				fprintf(fd, "no more slots in host table\n");				prthp(CLK_TCK);			}			syslog(LOG_ERR, "no more slots in host table");			Mflag = 0;			longjmp(jmpenv, 2); /* give up and be a slave */		}		/* if our home hash slot is occupied, find a free entry		 * in the hash table		 */		if (newhost_hash->name[0] != '\0') {			do {				ret = lasthfree;				if (++lasthfree > &hosttbl[NHOSTS])					lasthfree = &hosttbl[1];			} while (ret->name[0] != '\0');			if (!newhost_hash->head) {				/* Move an interloper using our home.  Use				 * scratch pointers in case the new head is				 * pointing to itself.				 */				f = newhost_hash->h_fwd;				b = newhost_hash->h_bak;				f->h_bak = ret;				b->h_fwd = ret;				f = newhost_hash->l_fwd;				b = newhost_hash->l_bak;				f->l_bak = ret;				b->l_fwd = ret;				bcopy(newhost_hash,ret,sizeof(*ret));				ret = newhost_hash;				ret->head = 1;				ret->h_fwd = ret;				ret->h_bak = ret;			} else {				/* link to an existing chain in our home				 */				ret->head = 0;				p = newhost_hash->h_bak;				ret->h_fwd = newhost_hash;				ret->h_bak = p;				p->h_fwd = ret;				newhost_hash->h_bak = ret;			}		} else {			ret = newhost_hash;			ret->head = 1;			ret->h_fwd = ret;			ret->h_bak = ret;		}		ret->addr = *addr;		ret->ntp = ntp;		(void)strncpy(ret->name, name, sizeof(ret->name));		ret->good = good_host_name(name);		ret->l_fwd = &self;		ret->l_bak = self.l_bak;		self.l_bak->l_fwd = ret;		self.l_bak = ret;		slvcount++;		ret->noanswer = 0;		ret->need_set = 1;	} else {		ret->noanswer = (ret->noanswer != 0);	}	/* need to clear sequence number anyhow */	ret->seq = 0;	return(ret);}/* * remove the machine with the given index in the host table. */struct hosttbl *remmach(htp)	struct hosttbl *htp;{	struct hosttbl *lprv, *hnxt, *f, *b;	if (trace)		fprintf(fd, "remove %s\n", htp->name);	/* get out of the lists */	htp->l_fwd->l_bak = lprv = htp->l_bak;	htp->l_bak->l_fwd = htp->l_fwd;	htp->h_fwd->h_bak = htp->h_bak;	htp->h_bak->h_fwd = hnxt = htp->h_fwd;	/* If we are in the home slot, pull up the chain */	if (htp->head && hnxt != htp) {		if (lprv == hnxt)			lprv = htp;		/* Use scratch pointers in case the new head is pointing to		 * itself.		 */		f = hnxt->h_fwd;		b = hnxt->h_bak;		f->h_bak = htp;		b->h_fwd = htp;		f = hnxt->l_fwd;		b = hnxt->l_bak;		f->l_bak = htp;		b->l_fwd = htp;		hnxt->head = 1;		bcopy(hnxt, htp, sizeof(*htp));		lasthfree = hnxt;	} else {		lasthfree = htp;	}	lasthfree->name[0] = '\0';	lasthfree->h_fwd = 0;	lasthfree->l_fwd = 0;	slvcount--;	return lprv;}/* * Remove all the machines from the host table that exist on the given * network.  This is called when a master transitions to a slave on a * given network. */voidrmnetmachs(ntp)	struct netinfo *ntp;{	struct hosttbl *htp;	if (trace)		prthp(CLK_TCK);	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {		if (ntp == htp->ntp)			htp = remmach(htp);	}	if (trace)		prthp(CLK_TCK);}voidmasterup(net)	struct netinfo *net;{	xmit(TSP_MASTERUP, 0, &net->dest_addr);	/*	 * Do not tell new slaves our time for a while.  This ensures	 * we do not tell them to start using our time, before we have	 * found a good master.	 */	(void)gettimeofday(&net->slvwait, 0);}voidnewslave(msg)	struct tsp *msg;{	struct hosttbl *htp;	struct tsp *answer, to;	struct timeval now;	if (!fromnet || fromnet->status != MASTER)		return;	htp = addmach(msg->tsp_name, &from,fromnet);	htp->seq = msg->tsp_seq;	if (trace)		prthp(0);	/*	 * If we are stable, send our time to the slave.	 * Do not go crazy if the date has been changed.	 */	(void)gettimeofday(&now, 0);	if (now.tv_sec >= fromnet->slvwait.tv_sec+3	    || now.tv_sec < fromnet->slvwait.tv_sec) {		to.tsp_type = TSP_SETTIME;		(void)strcpy(to.tsp_name, hostname);		(void)gettimeofday(&to.tsp_time, 0);		answer = acksend(&to, &htp->addr,				 htp->name, TSP_ACK,				 0, htp->noanswer);		if (answer) {			htp->need_set = 0;		} else {			syslog(LOG_WARNING,			       "no reply to initial SETTIME from %s",			       htp->name);			htp->noanswer = LOSTHOST;		}	}}/* * react to a TSP_QUIT: */voiddoquit(msg)	struct tsp *msg;{	if (fromnet->status == MASTER) {		if (!good_host_name(msg->tsp_name)) {			if (fromnet->quit_count <= 0) {				syslog(LOG_NOTICE,"untrusted %s told us QUIT",				       msg->tsp_name);				suppress(&from, msg->tsp_name, fromnet);				fromnet->quit_count = 1;				return;			}			syslog(LOG_NOTICE, "untrusted %s told us QUIT twice",			       msg->tsp_name);			fromnet->quit_count = 2;			fromnet->status = NOMASTER;		} else {			fromnet->status = SLAVE;		}		rmnetmachs(fromnet);		longjmp(jmpenv, 2);		/* give up and be a slave */	} else {		if (!good_host_name(msg->tsp_name)) {			syslog(LOG_NOTICE, "untrusted %s told us QUIT",			       msg->tsp_name);			fromnet->quit_count = 2;		}	}}voidtraceon(){	if (!fd) {		fd = fopen(_PATH_TIMEDLOG, "w");		if (!fd) {			trace = 0;			return;		}		fprintf(fd,"Tracing started at %s\n", date());	}	trace = 1;	get_goodgroup(1);	setstatus();	prthp(CLK_TCK);}voidtraceoff(msg)	char *msg;{	get_goodgroup(1);	setstatus();	prthp(CLK_TCK);	if (trace) {		fprintf(fd, msg, date());		(void)fclose(fd);		fd = 0;	}#ifdef GPROF	moncontrol(0);	_mcleanup();	moncontrol(1);#endif	trace = OFF;}#ifdef sgivoidlogwtmp(otime, ntime)	struct timeval *otime, *ntime;{	static struct utmp wtmp[2] = {		{"","",OTIME_MSG,0,OLD_TIME,0,0,0},		{"","",NTIME_MSG,0,NEW_TIME,0,0,0}	};	static char *wtmpfile = WTMP_FILE;	int f;	wtmp[0].ut_time = otime->tv_sec + (otime->tv_usec + 500000) / 1000000;	wtmp[1].ut_time = ntime->tv_sec + (ntime->tv_usec + 500000) / 1000000;	if (wtmp[0].ut_time == wtmp[1].ut_time)		return;	setutent();	(void)pututline(&wtmp[0]);	(void)pututline(&wtmp[1]);	endutent();	if ((f = open(wtmpfile, O_WRONLY|O_APPEND)) >= 0) {		(void) write(f, (char *)wtmp, sizeof(wtmp));		(void) close(f);	}}#endif /* sgi */

⌨️ 快捷键说明

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