Exemplo n.º 1
0
static int rep_wait_for_connection(replication *r,uint32_t msecto) {
	uint8_t i,l;
	struct timeval tvb,tv;
	uint32_t msec;
	gettimeofday(&tvb,NULL);
	for (;;) {
		l=1;
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->repsources[i].mode==CONNECTING) {
				r->fds[i].events = POLLOUT;
				l=0;
			} else {
				r->fds[i].events = 0;
			}
		}
		if (l) {	// finished
			return 0;
		}
		gettimeofday(&tv,NULL);
		if (tv.tv_usec < tvb.tv_usec) {
			tv.tv_usec+=1000000;
			tv.tv_sec--;
		}
		tv.tv_sec-=tvb.tv_sec;
		tv.tv_usec-=tvb.tv_usec;
		msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
		if (msec>=msecto) {
			syslog(LOG_NOTICE,"replicator: connect timed out");
			return -1; // timed out
		}
		if (poll(r->fds,r->srccnt,msecto-msec)<0) {
			if (errno!=EINTR && errno!=EAGAIN) {
				mfs_errlog_silent(LOG_NOTICE,"replicator: poll error");
				return -1;
			}
			continue;
		}
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->fds[i].revents & POLLHUP) {
				syslog(LOG_NOTICE,"replicator: connection lost");
				return -1;
			}
			if (r->fds[i].revents & POLLOUT) {
				if (tcpgetstatus(r->repsources[i].sock)<0) {
					mfs_errlog_silent(LOG_NOTICE,"replicator: connect error");
					return -1;
				}
				r->repsources[i].mode=IDLE;
			}
		}
	}
}
Exemplo n.º 2
0
void masterconn_write(masterconn *eptr) {
    packetstruct *pack;
    int32_t i;
    for (;;) {
        pack = eptr->outputhead;
        if (pack==NULL) {
            return;
        }
        i=write(eptr->sock,pack->startptr,pack->bytesleft);
        if (i<0) {
            if (errno!=EAGAIN) {
                mfs_errlog_silent(LOG_NOTICE,"write to Master error");
                eptr->mode = KILL;
            }
            return;
        }
        stats_bytesout+=i;
        pack->startptr+=i;
        pack->bytesleft-=i;
        if (pack->bytesleft>0) {
            return;
        }
        free(pack->packet);
        eptr->outputhead = pack->next;
        if (eptr->outputhead==NULL) {
            eptr->outputtail = &(eptr->outputhead);
        }
        free(pack);
    }
}
Exemplo n.º 3
0
int matomlserv_init(void) {
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on %s:%s",ListenHost,ListenPort);
		return -1;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort);

	matomlservhead = NULL;
	ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600);
	if (ChangelogSecondsToRemember>3600) {
		syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember);
		ChangelogSecondsToRemember=3600;
	}
	main_reloadregister(matomlserv_reload);
	main_destructregister(matomlserv_term);
    main_canexitregister(matomlserv_canexit);
	main_pollregister(matomlserv_desc,matomlserv_serve);
	main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status);
	return 0;
}
Exemplo n.º 4
0
int matomlserv_init(void) {
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
		mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on socket");
		return -1;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort);

	matomlservhead = NULL;
	main_reloadregister(matomlserv_reload);
	main_destructregister(matomlserv_term);
	main_pollregister(matomlserv_desc,matomlserv_serve);
	main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status);
	return 0;
}
Exemplo n.º 5
0
int csserv_init(void) {
	ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*");
	ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT);

	lsock = tcpsocket();
	if (lsock<0) {
		mfs_errlog(LOG_ERR,"main server module: can't create socket");
		return -1;
	}
	tcpnonblock(lsock);
	tcpnodelay(lsock);
	tcpreuseaddr(lsock);
	tcpresolve(ListenHost,ListenPort,&mylistenip,&mylistenport,1);
	if (tcpnumlisten(lsock,mylistenip,mylistenport,100)<0) {
		mfs_errlog(LOG_ERR,"main server module: can't listen on socket");
		return -1;
	}
	if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter");
	}
	mfs_arg_syslog(LOG_NOTICE,"main server module: listen on %s:%s",ListenHost,ListenPort);

	csservhead = NULL;
	main_reload_register(csserv_reload);
	main_destruct_register(csserv_term);
	main_poll_register(csserv_desc,csserv_serve);

	return 0;
}
Exemplo n.º 6
0
void masterconn_download_info(masterconn *eptr,const uint8_t *data,uint32_t length) {
    if (length!=1 && length!=8) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_INFO - wrong size (%"PRIu32"/1|8)",length);
        eptr->mode = KILL;
        return;
    }
    passert(data);
    if (length==1) {
        eptr->downloading = 0;
        syslog(LOG_NOTICE,"download start error");
        return;
    }
    eptr->filesize = get64bit(&data);
    eptr->dloffset = 0;
    eptr->downloadretrycnt = 0;
    eptr->dlstartuts = monotonic_useconds();
    if (eptr->downloading==1) {
        eptr->metafd = open("metadata_ml.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666);
    } else if (eptr->downloading==11 || eptr->downloading==12) {
        eptr->metafd = open("changelog_ml.tmp",O_WRONLY | O_TRUNC | O_CREAT,0666);
    } else {
        syslog(LOG_NOTICE,"unexpected MATOAN_DOWNLOAD_INFO packet");
        eptr->mode = KILL;
        return;
    }
    if (eptr->metafd<0) {
        mfs_errlog_silent(LOG_NOTICE,"error opening metafile");
        masterconn_download_end(eptr);
        return;
    }
    masterconn_download_next(eptr);
}
Exemplo n.º 7
0
void csserv_write(csserventry *eptr) {
	packetstruct *pack;
	int32_t i;
	for (;;) {
		pack = eptr->outputhead;
		if (pack==NULL) {
			return;
		}
		i=write(eptr->sock,pack->startptr,pack->bytesleft);
		if (i==0) {
//			syslog(LOG_NOTICE,"(write) connection closed");
			eptr->state = CLOSE;
			return;
		}
		if (i<0) {
			if (ERRNO_ERROR) {
				mfs_errlog_silent(LOG_NOTICE,"(write) write error");
				eptr->state = CLOSE;
			}
			return;
		}
		stats_bytesout+=i;
		pack->startptr+=i;
		pack->bytesleft-=i;
		if (pack->bytesleft>0) {
			return;
		}
		free(pack->packet);
		eptr->outputhead = pack->next;
		if (eptr->outputhead==NULL) {
			eptr->outputtail = &(eptr->outputhead);
		}
		free(pack);
	}
}
Exemplo n.º 8
0
static int rep_wait_for_connection(replication *r,uint32_t msecto) {
	uint8_t i,l;
	uint64_t st;
	uint32_t msec;
	st = monotonic_useconds();
	for (;;) {
		l=1;
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->repsources[i].mode==CONNECTING) {
				r->fds[i].events = POLLOUT;
				l=0;
			} else {
				r->fds[i].events = 0;
			}
		}
		if (l) {	// finished
			return 0;
		}
		msec = (monotonic_useconds()-st)/1000;
		if (msec>=msecto) {
			syslog(LOG_NOTICE,"replicator: connect timed out");
			return -1; // timed out
		}
		if (poll(r->fds,r->srccnt,msecto-msec)<0) {
			if (errno!=EINTR && ERRNO_ERROR) {
				mfs_errlog_silent(LOG_NOTICE,"replicator: poll error");
				return -1;
			}
			continue;
		}
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->fds[i].revents & POLLHUP) {
				syslog(LOG_NOTICE,"replicator: connection lost");
				return -1;
			}
			if (r->fds[i].revents & POLLOUT) {
				if (tcpgetstatus(r->repsources[i].sock)<0) {
					mfs_errlog_silent(LOG_NOTICE,"replicator: connect error");
					return -1;
				}
				r->repsources[i].mode=IDLE;
			}
		}
	}
}
Exemplo n.º 9
0
static int rep_read(repsrc *rs) {
	int32_t i;
	uint32_t type;
	uint32_t size;
	const uint8_t *ptr;
	while (rs->bytesleft>0) {
		i=read(rs->sock,rs->startptr,rs->bytesleft);
		if (i==0) {
			syslog(LOG_NOTICE,"replicator: connection lost");
			return -1;
		}
		if (i<0) {
			if (ERRNO_ERROR) {
				mfs_errlog_silent(LOG_NOTICE,"replicator: read error");
				return -1;
			}
			return 0;
		}
		replicator_bytesin(i);
//		stats_bytesin+=i;
		rs->startptr+=i;
		rs->bytesleft-=i;

		if (rs->bytesleft>0) {
			return 0;
		}

		if (rs->mode==HEADER) {
			ptr = rs->hdrbuff;
			type = get32bit(&ptr);
			size = get32bit(&ptr);
			if (type==ANTOAN_NOP && size==0) { // NOP
				rs->startptr = rs->hdrbuff;
				rs->bytesleft = 8;
				return 0;
			}

			if (rs->packet) {
				free(rs->packet);
			}
			if (size>0) {
				if (size>MAX_RECV_PACKET_SIZE) {
					syslog(LOG_WARNING,"replicator: packet too long (%"PRIu32"/%u)",size,MAX_RECV_PACKET_SIZE);
					return -1;
				}
				rs->packet = malloc(size);
				passert(rs->packet);
				rs->startptr = rs->packet;
			} else {
				rs->packet = NULL;
			}
			rs->bytesleft = size;
			rs->mode = DATA;
		}
	}
	return 0;
}
Exemplo n.º 10
0
int masterconn_download_end(masterconn *eptr) {
    eptr->downloading=0;
    masterconn_createpacket(eptr,ANTOMA_DOWNLOAD_END,0);
    if (eptr->metafd>=0) {
        if (close(eptr->metafd)<0) {
            mfs_errlog_silent(LOG_NOTICE,"error closing metafile");
            eptr->metafd=-1;
            return -1;
        }
        eptr->metafd=-1;
    }
    return 0;
}
Exemplo n.º 11
0
void matomlserv_reload(void) {
	char *oldListenHost,*oldListenPort;
	int newlsock;

	oldListenHost = ListenHost;
	oldListenPort = ListenPort;
	ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*");
	ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419");
	if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
		free(oldListenHost);
		free(oldListenPort);
		mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
		return;
	}

	newlsock = tcpsocket();
	if (newlsock<0) {
		mfs_errlog(LOG_WARNING,"master <-> metaloggers module: socket address has changed, but can't create new socket");
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		return;
	}
	tcpnonblock(newlsock);
	tcpnodelay(newlsock);
	tcpreuseaddr(newlsock);
	if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter");
	}
	if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		tcpclose(newlsock);
		return;
	}
	mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
	free(oldListenHost);
	free(oldListenPort);
	tcpclose(lsock);
	lsock = newlsock;

	ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600);
	if (ChangelogSecondsToRemember>3600) {
		syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember);
		ChangelogSecondsToRemember=3600;
	}
}
Exemplo n.º 12
0
static int rep_receive_all_packets(replication *r,uint32_t msecto) {
	uint8_t i,l;
	struct timeval tvb,tv;
	uint32_t msec;
	gettimeofday(&tvb,NULL);
	for (;;) {
		l=1;
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->repsources[i].bytesleft>0) {
				r->fds[i].events = POLLIN;
				l=0;
			} else {
				r->fds[i].events = 0;
			}
		}
		if (l) {	// finished
			return 0;
		}
		gettimeofday(&tv,NULL);
		if (tv.tv_usec < tvb.tv_usec) {
			tv.tv_usec+=1000000;
			tv.tv_sec--;
		}
		tv.tv_sec-=tvb.tv_sec;
		tv.tv_usec-=tvb.tv_usec;
		msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
		if (msec>=msecto) {
			syslog(LOG_NOTICE,"replicator: receive timed out");
			return -1; // timed out
		}
		if (poll(r->fds,r->srccnt,msecto-msec)<0) {
			if (errno!=EINTR && errno!=EAGAIN) {
				mfs_errlog_silent(LOG_NOTICE,"replicator: poll error");
				return -1;
			}
			continue;
		}
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->fds[i].revents & POLLHUP) {
				syslog(LOG_NOTICE,"replicator: connection lost");
				return -1;
			}
			if (r->fds[i].revents & POLLIN) {
				if (rep_read(r->repsources+i)<0) {
					return -1;
				}
			}
		}
	}
}
Exemplo n.º 13
0
void masterconn_connecttest(masterconn *eptr) {
    int status;

    status = tcpgetstatus(eptr->sock);
    if (status) {
        mfs_errlog_silent(LOG_WARNING,"connection failed, error");
        tcpclose(eptr->sock);
        eptr->sock = -1;
        eptr->mode = FREE;
        eptr->masteraddrvalid = 0;
    } else {
        syslog(LOG_NOTICE,"connected to Master");
        masterconn_connected(eptr);
    }
}
Exemplo n.º 14
0
void csserv_reload(void) {
	char *oldListenHost,*oldListenPort;
	int newlsock;

//	ThreadedServer = 1-ThreadedServer;

	oldListenHost = ListenHost;
	oldListenPort = ListenPort;
	ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*");
	ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT);
	if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
		free(oldListenHost);
		free(oldListenPort);
		mfs_arg_syslog(LOG_NOTICE,"main server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
		return;
	}

	newlsock = tcpsocket();
	if (newlsock<0) {
		mfs_errlog(LOG_WARNING,"main server module: socket address has changed, but can't create new socket");
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		return;
	}
	tcpnonblock(newlsock);
	tcpnodelay(newlsock);
	tcpreuseaddr(newlsock);
	if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
		mfs_arg_errlog(LOG_ERR,"main server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
		free(ListenHost);
		free(ListenPort);
		ListenHost = oldListenHost;
		ListenPort = oldListenPort;
		tcpclose(newlsock);
		return;
	}
	if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
		mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter");
	}
	mfs_arg_syslog(LOG_NOTICE,"main server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
	free(oldListenHost);
	free(oldListenPort);
	tcpclose(lsock);
	lsock = newlsock;
}
Exemplo n.º 15
0
static int rep_write(repsrc *rs) {
	int i;
	i = write(rs->sock,rs->startptr,rs->bytesleft);
	if (i==0) {
		syslog(LOG_NOTICE,"replicator: connection lost");
		return -1;
	}
	if (i<0) {
		if (errno!=EAGAIN) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: write error");
			return -1;
		}
		return 0;
	}
//	stats_bytesin+=i;
	rs->startptr+=i;
	rs->bytesleft-=i;
	return 0;
}
Exemplo n.º 16
0
static int rep_send_all_packets(replication *r,uint32_t msecto) {
	uint8_t i,l;
	uint64_t st;
	uint32_t msec;
	st = monotonic_useconds();
	for (;;) {
		l=1;
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->repsources[i].bytesleft>0) {
				r->fds[i].events = POLLOUT;
				l=0;
			} else {
				r->fds[i].events = 0;
			}
		}
		if (l) {	// finished
			return 0;
		}
		msec = (monotonic_useconds()-st)/1000;
		if (msec>=msecto) {
			syslog(LOG_NOTICE,"replicator: send timed out");
			return -1; // timed out
		}
		if (poll(r->fds,r->srccnt,msecto-msec)<0) {
			if (errno!=EINTR && ERRNO_ERROR) {
				mfs_errlog_silent(LOG_NOTICE,"replicator: poll error");
				return -1;
			}
			continue;
		}
		for (i=0 ; i<r->srccnt ; i++) {
			if (r->fds[i].revents & POLLHUP) {
				syslog(LOG_NOTICE,"replicator: connection lost");
				return -1;
			}
			if (r->fds[i].revents & POLLOUT) {
				if (rep_write(r->repsources+i)<0) {
					return -1;
				}
			}
		}
	}
}
Exemplo n.º 17
0
void matomlserv_download_data(matomlserventry *eptr,const uint8_t *data,uint32_t length) {
	uint8_t *ptr;
	uint64_t offset;
	uint32_t leng;
	uint32_t crc;
	ssize_t ret;

	if (length!=12) {
		syslog(LOG_NOTICE,"MLTOMA_DOWNLOAD_DATA - wrong size (%"PRIu32"/12)",length);
		eptr->mode=KILL;
		return;
	}
	if (eptr->metafd<0) {
		syslog(LOG_NOTICE,"MLTOMA_DOWNLOAD_DATA - file not opened");
		eptr->mode=KILL;
		return;
	}
	offset = get64bit(&data);
	leng = get32bit(&data);
	ptr = matomlserv_createpacket(eptr,MATOML_DOWNLOAD_DATA,16+leng);
	put64bit(&ptr,offset);
	put32bit(&ptr,leng);
#ifdef HAVE_PREAD
	ret = pread(eptr->metafd,ptr+4,leng,offset);
#else /* HAVE_PWRITE */
	lseek(eptr->metafd,offset,SEEK_SET);
	ret = read(eptr->metafd,ptr+4,leng);
#endif /* HAVE_PWRITE */
	if (ret!=(ssize_t)leng) {
		mfs_errlog_silent(LOG_NOTICE,"error reading metafile");
		eptr->mode=KILL;
		return;
	}
	crc = mycrc32(0,ptr+4,leng);
	put32bit(&ptr,crc);
}
Exemplo n.º 18
0
/* srcs: srccnt * (chunkid:64 version:32 ip:32 port:16) */
uint8_t replicate(uint64_t chunkid,uint32_t version,uint8_t srccnt,const uint8_t *srcs) {
	replication r;
	uint8_t status,i,vbuffs,first;
	uint16_t b,blocks;
	uint32_t xcrc,crc;
	uint8_t *wptr;
	const uint8_t *rptr;
	int s;

	if (srccnt==0) {
		return ERROR_EINVAL;
	}

//	syslog(LOG_NOTICE,"replication begin (chunkid:%08"PRIX64",version:%04"PRIX32",srccnt:%"PRIu8")",chunkid,version,srccnt);

	pthread_mutex_lock(&statslock);
	stats_repl++;
	pthread_mutex_unlock(&statslock);

// init replication structure
	r.chunkid = chunkid;
	r.version = version;
	r.srccnt = 0;
	r.created = 0;
	r.opened = 0;
	r.fds = malloc(sizeof(struct pollfd)*srccnt);
	passert(r.fds);
	r.repsources = malloc(sizeof(repsrc)*srccnt);
	passert(r.repsources);
	if (srccnt>1) {
		r.xorbuff = malloc(65536+4);
		passert(r.xorbuff);
	} else {
		r.xorbuff = NULL;
	}
// create chunk
	status = hdd_create(chunkid,0);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_create status: %u",status);
		rep_cleanup(&r);
		return status;
	}
	r.created = 1;
// init sources
	r.srccnt = srccnt;
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].chunkid = get64bit(&srcs);
		r.repsources[i].version = get32bit(&srcs);
		r.repsources[i].ip = get32bit(&srcs);
		r.repsources[i].port = get16bit(&srcs);
		r.repsources[i].sock = -1;
		r.repsources[i].packet = NULL;
	}
// connect
	for (i=0 ; i<srccnt ; i++) {
		s = tcpsocket();
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: socket error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		r.repsources[i].sock = s;
		r.fds[i].fd = s;
		if (tcpnonblock(s)<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: nonblock error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		s = tcpnumconnect(s,r.repsources[i].ip,r.repsources[i].port);
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: connect error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		if (s==0) {
			r.repsources[i].mode = IDLE;
		} else {
			r.repsources[i].mode = CONNECTING;
		}
	}
	if (rep_wait_for_connection(&r,CONNMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_CANTCONNECT;
	}
// open chunk
	status = hdd_open(chunkid);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_open status: %u",status);
		rep_cleanup(&r);
		return status;
	}
	r.opened = 1;
// get block numbers
	for (i=0 ; i<srccnt ; i++) {
		wptr = rep_create_packet(r.repsources+i,CSTOCS_GET_CHUNK_BLOCKS,8+4);
		if (wptr==NULL) {
			syslog(LOG_NOTICE,"replicator: out of memory");
			rep_cleanup(&r);
			return ERROR_OUTOFMEMORY;
		}
		put64bit(&wptr,r.repsources[i].chunkid);
		put32bit(&wptr,r.repsources[i].version);
	}
// send packet
	if (rep_send_all_packets(&r,SENDMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// receive answers
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].mode = HEADER;
		r.repsources[i].startptr = r.repsources[i].hdrbuff;
		r.repsources[i].bytesleft = 8;
	}
	if (rep_receive_all_packets(&r,RECVMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// get block no
	blocks = 0;
	for (i=0 ; i<srccnt ; i++) {
		uint32_t type,size;
		uint64_t pchid;
		uint32_t pver;
		uint16_t pblocks;
		uint8_t pstatus;
		rptr = r.repsources[i].hdrbuff;
		type = get32bit(&rptr);
		size = get32bit(&rptr);
		rptr = r.repsources[i].packet;
		if (rptr==NULL || type!=CSTOCS_GET_CHUNK_BLOCKS_STATUS || size!=15) {
			syslog(LOG_WARNING,"replicator: got wrong answer (type/size) from (%08"PRIX32":%04"PRIX16")",r.repsources[i].ip,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_DISCONNECTED;
		}
		pchid = get64bit(&rptr);
		pver = get32bit(&rptr);
		pblocks = get16bit(&rptr);
		pstatus = get8bit(&rptr);
		if (pchid!=r.repsources[i].chunkid) {
			syslog(LOG_WARNING,"replicator: got wrong answer (chunk_status:chunkid:%"PRIX64"/%"PRIX64") from (%08"PRIX32":%04"PRIX16")",pchid,r.repsources[i].chunkid,r.repsources[i].ip,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_WRONGCHUNKID;
		}
		if (pver!=r.repsources[i].version) {
			syslog(LOG_WARNING,"replicator: got wrong answer (chunk_status:version:%"PRIX32"/%"PRIX32") from (%08"PRIX32":%04"PRIX16")",pver,r.repsources[i].version,r.repsources[i].ip,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_WRONGVERSION;
		}
		if (pstatus!=STATUS_OK) {
			syslog(LOG_NOTICE,"replicator: got status: %u from (%08"PRIX32":%04"PRIX16")",pstatus,r.repsources[i].ip,r.repsources[i].port);
			rep_cleanup(&r);
			return pstatus;
		}
		r.repsources[i].blocks = pblocks;
		if (pblocks>blocks) {
			blocks=pblocks;
		}
	}
// create read request
	for (i=0 ; i<srccnt ; i++) {
		if (r.repsources[i].blocks>0) {
			uint32_t leng;
			wptr = rep_create_packet(r.repsources+i,CUTOCS_READ,8+4+4+4);
			if (wptr==NULL) {
				syslog(LOG_NOTICE,"replicator: out of memory");
				rep_cleanup(&r);
				return ERROR_OUTOFMEMORY;
			}
			leng = r.repsources[i].blocks*0x10000;
			put64bit(&wptr,r.repsources[i].chunkid);
			put32bit(&wptr,r.repsources[i].version);
			put32bit(&wptr,0);
			put32bit(&wptr,leng);
		} else {
			rep_no_packet(r.repsources+i);
		}
	}
// send read request
	if (rep_send_all_packets(&r,SENDMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// receive data and write to hdd
	for (b=0 ; b<blocks ; b++) {
// prepare receive
		for (i=0 ; i<srccnt ; i++) {
			if (b<r.repsources[i].blocks) {
				r.repsources[i].mode = HEADER;
				r.repsources[i].startptr = r.repsources[i].hdrbuff;
				r.repsources[i].bytesleft = 8;
			} else {
				r.repsources[i].mode = IDLE;
				r.repsources[i].bytesleft = 0;
			}
		}
// receive data
		if (rep_receive_all_packets(&r,RECVMSECTO)<0) {
			rep_cleanup(&r);
			return ERROR_DISCONNECTED;
		}
// check packets
		vbuffs = 0;
		for (i=0 ; i<srccnt ; i++) {
			if (r.repsources[i].mode!=IDLE) {
				uint32_t type,size;
				uint64_t pchid;
				uint16_t pblocknum;
				uint16_t poffset;
				uint32_t psize;
				uint8_t pstatus;
				rptr = r.repsources[i].hdrbuff;
				type = get32bit(&rptr);
				size = get32bit(&rptr);
				rptr = r.repsources[i].packet;
				if (rptr==NULL) {
					rep_cleanup(&r);
					return ERROR_DISCONNECTED;
				}
				if (type==CSTOCU_READ_STATUS && size==9) {
					pchid = get64bit(&rptr);
					pstatus = get8bit(&rptr);
					rep_cleanup(&r);
					if (pchid!=r.repsources[i].chunkid) {
						syslog(LOG_WARNING,"replicator: got wrong answer (read_status:chunkid:%"PRIX64"/%"PRIX64") from (%08"PRIX32":%04"PRIX16")",pchid,r.repsources[i].chunkid,r.repsources[i].ip,r.repsources[i].port);
						return ERROR_WRONGCHUNKID;
					}
					if (pstatus==STATUS_OK) {	// got status too early or got incorrect packet
						syslog(LOG_WARNING,"replicator: got unexpected ok status from (%08"PRIX32":%04"PRIX16")",r.repsources[i].ip,r.repsources[i].port);
						return ERROR_DISCONNECTED;
					}
					syslog(LOG_NOTICE,"replicator: got status: %u from (%08"PRIX32":%04"PRIX16")",pstatus,r.repsources[i].ip,r.repsources[i].port);
					return pstatus;
				} else if (type==CSTOCU_READ_DATA && size==20+65536) {
					pchid = get64bit(&rptr);
					pblocknum = get16bit(&rptr);
					poffset = get16bit(&rptr);
					psize = get32bit(&rptr);
					if (pchid!=r.repsources[i].chunkid) {
						syslog(LOG_WARNING,"replicator: got wrong answer (read_data:chunkid:%"PRIX64"/%"PRIX64") from (%08"PRIX32":%04"PRIX16")",pchid,r.repsources[i].chunkid,r.repsources[i].ip,r.repsources[i].port);
						rep_cleanup(&r);
						return ERROR_WRONGCHUNKID;
					}
					if (pblocknum!=b) {
						syslog(LOG_WARNING,"replicator: got wrong answer (read_data:blocknum:%"PRIu16"/%"PRIu16") from (%08"PRIX32":%04"PRIX16")",pblocknum,b,r.repsources[i].ip,r.repsources[i].port);
						rep_cleanup(&r);
						return ERROR_DISCONNECTED;
					}
					if (poffset!=0) {
						syslog(LOG_WARNING,"replicator: got wrong answer (read_data:offset:%"PRIu16") from (%08"PRIX32":%04"PRIX16")",poffset,r.repsources[i].ip,r.repsources[i].port);
						rep_cleanup(&r);
						return ERROR_WRONGOFFSET;
					}
					if (psize!=65536) {
						syslog(LOG_WARNING,"replicator: got wrong answer (read_data:size:%"PRIu32") from (%08"PRIX32":%04"PRIX16")",psize,r.repsources[i].ip,r.repsources[i].port);
						rep_cleanup(&r);
						return ERROR_WRONGSIZE;
					}
				} else {
					syslog(LOG_WARNING,"replicator: got wrong answer (type/size) from (%08"PRIX32":%04"PRIX16")",r.repsources[i].ip,r.repsources[i].port);
					rep_cleanup(&r);
					return ERROR_DISCONNECTED;
				}
				vbuffs++;
			}
		}
// write data
		if (vbuffs==0) {	// no buffers ? - it should never happen
			syslog(LOG_WARNING,"replicator: no data received for block: %"PRIu16,b);
			rep_cleanup(&r);
			return ERROR_DISCONNECTED;
		} else if (vbuffs==1) { // xor not needed, so just find block and write it
			for (i=0 ; i<srccnt ; i++) {
				if (r.repsources[i].mode!=IDLE) {
					rptr = r.repsources[i].packet;
					status = hdd_write(chunkid,0,b,rptr+20,0,65536,rptr+16);
					if (status!=STATUS_OK) {
						syslog(LOG_WARNING,"replicator: write status: %u",status);
						rep_cleanup(&r);
						return status;
					}
				}
			}
		} else {
			first=1;
			if (vbuffs&1) {
				xcrc = 0;
			} else {
				xcrc = 0xD7978EEBU; // = mycrc32_zeroblock(0,0x10000);
			}
			for (i=0 ; i<srccnt ; i++) {
				if (r.repsources[i].mode!=IDLE) {
					rptr = r.repsources[i].packet;
					rptr+=16;	// skip chunkid,blockno,offset and size
					if (first) {
						memcpy(r.xorbuff+4,rptr+4,65536);
						first=0;
					} else {
						xordata(r.xorbuff+4,rptr+4,65536);
					}
					crc = get32bit(&rptr);
					if (crc!=mycrc32(0,rptr,65536)) {
						syslog(LOG_WARNING,"replicator: received data with wrong checksum from (%08"PRIX32":%04"PRIX16")",r.repsources[i].ip,r.repsources[i].port);
						rep_cleanup(&r);
						return ERROR_CRC;
					}
					xcrc^=crc;
				}
			}
			wptr = r.xorbuff;
			put32bit(&wptr,xcrc);
			status = hdd_write(chunkid,0,b,r.xorbuff+4,0,65536,r.xorbuff);
			if (status!=STATUS_OK) {
				syslog(LOG_WARNING,"replicator: xor write status: %u",status);
				rep_cleanup(&r);
				return status;
			}
		}
	}
// receive status
	for (i=0 ; i<srccnt ; i++) {
		if (r.repsources[i].blocks>0) {
//			if (r.repsources[i].packet) {
//				free(r.repsources[i].packet);
//				r.repsources[i].packet=NULL;
//			}
			r.repsources[i].mode = HEADER;
			r.repsources[i].startptr = r.repsources[i].hdrbuff;
			r.repsources[i].bytesleft = 8;
		} else {
			r.repsources[i].mode = IDLE;
			r.repsources[i].bytesleft = 0;
		}
	}
	if (rep_receive_all_packets(&r,RECVMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
	for (i=0 ; i<srccnt ; i++) {
		if (r.repsources[i].blocks>0) {
			uint32_t type,size;
			uint64_t pchid;
			uint8_t pstatus;
			rptr = r.repsources[i].hdrbuff;
			type = get32bit(&rptr);
			size = get32bit(&rptr);
			rptr = r.repsources[i].packet;
			if (rptr==NULL || type!=CSTOCU_READ_STATUS || size!=9) {
				syslog(LOG_WARNING,"replicator: got wrong answer (type/size) from (%08"PRIX32":%04"PRIX16")",r.repsources[i].ip,r.repsources[i].port);
				rep_cleanup(&r);
				return ERROR_DISCONNECTED;
			}
			pchid = get64bit(&rptr);
			pstatus = get8bit(&rptr);
			if (pchid!=r.repsources[i].chunkid) {
				syslog(LOG_WARNING,"replicator: got wrong answer (read_status:chunkid:%"PRIX64"/%"PRIX64") from (%08"PRIX32":%04"PRIX16")",pchid,r.repsources[i].chunkid,r.repsources[i].ip,r.repsources[i].port);
				rep_cleanup(&r);
				return ERROR_WRONGCHUNKID;
			}
			if (pstatus!=STATUS_OK) {
				syslog(LOG_NOTICE,"replicator: got status: %u from (%08"PRIX32":%04"PRIX16")",pstatus,r.repsources[i].ip,r.repsources[i].port);
				rep_cleanup(&r);
				return pstatus;
			}
		}
	}
// close chunk and change version
	status = hdd_close(chunkid);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_close status: %u",status);
		rep_cleanup(&r);
		return status;
	}
	r.opened = 0;
	status = hdd_version(chunkid,0,version);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_version status: %u",status);
		rep_cleanup(&r);
		return status;
	}
	r.created = 0;
	rep_cleanup(&r);
	return STATUS_OK;
}
Exemplo n.º 19
0
void masterconn_download_data(masterconn *eptr,const uint8_t *data,uint32_t length) {
    uint64_t offset;
    uint32_t leng;
    uint32_t crc;
    ssize_t ret;
    if (eptr->metafd<0) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - file not opened");
        eptr->mode = KILL;
        return;
    }
    if (length<16) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+data)",length);
        eptr->mode = KILL;
        return;
    }
    passert(data);
    offset = get64bit(&data);
    leng = get32bit(&data);
    crc = get32bit(&data);
    if (leng+16!=length) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - wrong size (%"PRIu32"/16+%"PRIu32")",length,leng);
        eptr->mode = KILL;
        return;
    }
    if (offset!=eptr->dloffset) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - unexpected file offset (%"PRIu64"/%"PRIu64")",offset,eptr->dloffset);
        eptr->mode = KILL;
        return;
    }
    if (offset+leng>eptr->filesize) {
        syslog(LOG_NOTICE,"MATOAN_DOWNLOAD_DATA - unexpected file size (%"PRIu64"/%"PRIu64")",offset+leng,eptr->filesize);
        eptr->mode = KILL;
        return;
    }
#ifdef HAVE_PWRITE
    ret = pwrite(eptr->metafd,data,leng,offset);
#else /* HAVE_PWRITE */
    lseek(eptr->metafd,offset,SEEK_SET);
    ret = write(eptr->metafd,data,leng);
#endif /* HAVE_PWRITE */
    if (ret!=(ssize_t)leng) {
        mfs_errlog_silent(LOG_NOTICE,"error writing metafile");
        if (eptr->downloadretrycnt>=5) {
            masterconn_download_end(eptr);
        } else {
            eptr->downloadretrycnt++;
            masterconn_download_next(eptr);
        }
        return;
    }
    if (crc!=mycrc32(0,data,leng)) {
        syslog(LOG_NOTICE,"metafile data crc error");
        if (eptr->downloadretrycnt>=5) {
            masterconn_download_end(eptr);
        } else {
            eptr->downloadretrycnt++;
            masterconn_download_next(eptr);
        }
        return;
    }
    if (fsync(eptr->metafd)<0) {
        mfs_errlog_silent(LOG_NOTICE,"error syncing metafile");
        if (eptr->downloadretrycnt>=5) {
            masterconn_download_end(eptr);
        } else {
            eptr->downloadretrycnt++;
            masterconn_download_next(eptr);
        }
        return;
    }
    eptr->dloffset+=leng;
    eptr->downloadretrycnt=0;
    masterconn_download_next(eptr);
}
Exemplo n.º 20
0
void csserv_serve(struct pollfd *pdesc) {
	double now;
	csserventry *eptr,**kptr;
	packetstruct *pptr,*paptr;
	int ns;

	now = monotonic_seconds();

	if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
		ns=tcpaccept(lsock);
		if (ns<0) {
			mfs_errlog_silent(LOG_NOTICE,"accept error");
		} else {
			tcpnonblock(ns);
			tcpnodelay(ns);
			eptr = malloc(sizeof(csserventry));
			passert(eptr);
			eptr->next = csservhead;
			csservhead = eptr;
			eptr->state = IDLE;
			eptr->mode = HEADER;
			eptr->sock = ns;
			eptr->pdescpos = -1;
			eptr->lastread = now;
			eptr->lastwrite = now;
			eptr->inputpacket.bytesleft = 8;
			eptr->inputpacket.startptr = eptr->hdrbuff;
			eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
			eptr->outputtail = &(eptr->outputhead);
			eptr->jobid = 0;

			eptr->idlejobs = NULL;
		}
	}

	for (eptr=csservhead ; eptr ; eptr=eptr->next) {
		if (eptr->pdescpos>=0 && (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP))) {
			eptr->state = CLOSE;
		}
		if (eptr->pdescpos>=0 && (pdesc[eptr->pdescpos].revents & POLLIN) && eptr->state==IDLE) {
			eptr->lastread = now;
			csserv_read(eptr);
		}
		if (eptr->state==IDLE && eptr->lastwrite+(CSSERV_TIMEOUT/3.0)<now && eptr->outputhead==NULL) {
			csserv_create_packet(eptr,ANTOAN_NOP,0);
		}
		if (eptr->pdescpos>=0 && (pdesc[eptr->pdescpos].revents & POLLOUT) && eptr->state==IDLE) {
			eptr->lastwrite = now;
			csserv_write(eptr);
		}
		if (eptr->state==IDLE && eptr->lastread+CSSERV_TIMEOUT<now) {
//			syslog(LOG_NOTICE,"csserv: connection timed out");
			eptr->state = CLOSE;
		}
	}

	kptr = &csservhead;
	while ((eptr=*kptr)) {
		if (eptr->state == CLOSE) {
			tcpclose(eptr->sock);
			csserv_close(eptr);
			if (eptr->inputpacket.packet) {
				free(eptr->inputpacket.packet);
			}
//			wptr = eptr->todolist;
//			while (wptr) {
//				waptr = wptr;
//				wptr = wptr->next;
//				free(waptr);
//			}
			pptr = eptr->outputhead;
			while (pptr) {
				if (pptr->packet) {
					free(pptr->packet);
				}
				paptr = pptr;
				pptr = pptr->next;
				free(paptr);
			}
			*kptr = eptr->next;
			free(eptr);
		} else {
			kptr = &(eptr->next);
		}
	}
}
Exemplo n.º 21
0
/* srcs: srccnt * (chunkid:64 version:32 ip:32 port:16) */
uint8_t replicate(uint64_t chunkid,uint32_t version,const uint32_t xormasks[4],uint8_t srccnt,const uint8_t *srcs) {
	replication r;
	uint8_t status,i,j,vbuffs,first;
	uint16_t b,blocks;
	uint32_t xcrc[4],crc;
	uint32_t codeindex,codeword;
	uint8_t *wptr;
	const uint8_t *rptr;
	int s;

	if (srccnt==0) {
		return ERROR_EINVAL;
	}

//	syslog(LOG_NOTICE,"replication begin (chunkid:%08"PRIX64",version:%04"PRIX32",srccnt:%"PRIu8")",chunkid,version,srccnt);

	pthread_mutex_lock(&statslock);
	stats_repl++;
	pthread_mutex_unlock(&statslock);

// init replication structure
	r.chunkid = chunkid;
	r.version = version;
	r.srccnt = 0;
	r.created = 0;
	r.opened = 0;
	r.fds = malloc(sizeof(struct pollfd)*srccnt);
	passert(r.fds);
	r.repsources = malloc(sizeof(repsrc)*srccnt);
	passert(r.repsources);
	if (srccnt>1) {
		r.xorbuff = malloc(MFSBLOCKSIZE+4);
		passert(r.xorbuff);
	} else {
		r.xorbuff = NULL;
	}
// create chunk
	status = hdd_create(chunkid,0);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_create status: %s",mfsstrerr(status));
		rep_cleanup(&r);
		return status;
	}
	r.created = 1;
// init sources
	r.srccnt = srccnt;
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].chunkid = get64bit(&srcs);
		r.repsources[i].version = get32bit(&srcs);
		r.repsources[i].ip = get32bit(&srcs);
		r.repsources[i].port = get16bit(&srcs);
		r.repsources[i].sock = -1;
		r.repsources[i].packet = NULL;
	}
// connect
	for (i=0 ; i<srccnt ; i++) {
		s = tcpsocket();
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: socket error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		r.repsources[i].sock = s;
		r.fds[i].fd = s;
		if (tcpnonblock(s)<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: nonblock error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		s = tcpnumconnect(s,r.repsources[i].ip,r.repsources[i].port);
		if (s<0) {
			mfs_errlog_silent(LOG_NOTICE,"replicator: connect error");
			rep_cleanup(&r);
			return ERROR_CANTCONNECT;
		}
		if (s==0) {
			r.repsources[i].mode = IDLE;
		} else {
			r.repsources[i].mode = CONNECTING;
		}
	}
	if (rep_wait_for_connection(&r,CONNMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_CANTCONNECT;
	}
// disable Nagle
	for (i=0 ; i<srccnt ; i++) {
		tcpnodelay(r.repsources[i].sock);
	}
// open chunk
	status = hdd_open(chunkid,0);
	if (status!=STATUS_OK) {
		syslog(LOG_NOTICE,"replicator: hdd_open status: %s",mfsstrerr(status));
		rep_cleanup(&r);
		return status;
	}
	r.opened = 1;
// get block numbers
	for (i=0 ; i<srccnt ; i++) {
		wptr = rep_create_packet(r.repsources+i,ANTOCS_GET_CHUNK_BLOCKS,8+4);
		if (wptr==NULL) {
			syslog(LOG_NOTICE,"replicator: out of memory");
			rep_cleanup(&r);
			return ERROR_OUTOFMEMORY;
		}
		put64bit(&wptr,r.repsources[i].chunkid);
		put32bit(&wptr,r.repsources[i].version);
	}
// send packet
	if (rep_send_all_packets(&r,SENDMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// receive answers
	for (i=0 ; i<srccnt ; i++) {
		r.repsources[i].mode = HEADER;
		r.repsources[i].startptr = r.repsources[i].hdrbuff;
		r.repsources[i].bytesleft = 8;
	}
	if (rep_receive_all_packets(&r,RECVMSECTO)<0) {
		rep_cleanup(&r);
		return ERROR_DISCONNECTED;
	}
// get # of blocks
	blocks = 0;
	for (i=0 ; i<srccnt ; i++) {
		uint32_t type,size;
		uint64_t pchid;
		uint32_t pver;
		uint16_t pblocks;
		uint8_t pstatus;
		uint32_t ip;
		rptr = r.repsources[i].hdrbuff;
		type = get32bit(&rptr);
		size = get32bit(&rptr);
		rptr = r.repsources[i].packet;
		ip = r.repsources[i].ip;
		if (rptr==NULL || type!=CSTOAN_CHUNK_BLOCKS || size!=15) {
			syslog(LOG_WARNING,"replicator,get # of blocks: got wrong answer (type:0x%08"PRIX32"/size:0x%08"PRIX32") from (%u.%u.%u.%u:%04"PRIX16")",type,size,(ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,ip&0xFF,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_DISCONNECTED;
		}
		pchid = get64bit(&rptr);
		pver = get32bit(&rptr);
		pblocks = get16bit(&rptr);
		pstatus = get8bit(&rptr);
		if (pchid!=r.repsources[i].chunkid) {
			syslog(LOG_WARNING,"replicator,get # of blocks: got wrong answer (chunk_status:chunkid:%"PRIX64"/%"PRIX64") from (%u.%u.%u.%u:%04"PRIX16")",pchid,r.repsources[i].chunkid,(ip>>24)&0xFF,(ip>>16)&0xFF,(ip>>8)&0xFF,ip&0xFF,r.repsources[i].port);
			rep_cleanup(&r);
			return ERROR_WRONGCHUNKID;
		}
Exemplo n.º 22
0
void matomlserv_serve(struct pollfd *pdesc) {
	uint32_t now=main_time();
	matomlserventry *eptr,**kptr;
	packetstruct *pptr,*paptr;
	int ns;
	static uint64_t lastaction = 0;
	uint64_t unow;
	uint32_t timeoutadd;

	if (lastaction==0) {
		lastaction = main_precise_utime();
	}

	if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
		ns=tcpaccept(lsock);
		if (ns<0) {
			mfs_errlog_silent(LOG_NOTICE,"Master<->ML socket: accept error");
		} else {
			tcpnonblock(ns);
			tcpnodelay(ns);
			eptr = malloc(sizeof(matomlserventry));
			passert(eptr);
			eptr->next = matomlservhead;
			matomlservhead = eptr;
			eptr->sock = ns;
			eptr->pdescpos = -1;
			eptr->mode = HEADER;
			eptr->lastread = now;
			eptr->lastwrite = now;
			eptr->inputpacket.next = NULL;
			eptr->inputpacket.bytesleft = 8;
			eptr->inputpacket.startptr = eptr->hdrbuff;
			eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
			eptr->outputtail = &(eptr->outputhead);
			eptr->timeout = 10;

			tcpgetpeer(eptr->sock,&(eptr->servip),NULL);
			eptr->servstrip = matomlserv_makestrip(eptr->servip);
			eptr->version=0;
			eptr->metafd=-1;
			eptr->chain1fd=-1;
			eptr->chain2fd=-1;
            eptr->logindex=-1;
            eptr->logf=NULL;
            eptr->currentversion=0;
		}
	}

// read
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if (eptr->pdescpos>=0) {
			if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
				eptr->mode = KILL;
			}
			if ((pdesc[eptr->pdescpos].revents & POLLIN) && eptr->mode!=KILL) {
				eptr->lastread = now;
				matomlserv_read(eptr);
			}
		}
	}

// timeout fix
	unow = main_precise_utime();
	timeoutadd = (unow-lastaction)/1000000;
	if (timeoutadd) {
		for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
			eptr->lastread += timeoutadd;
		}
	}
	lastaction = unow;

// write
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if ((uint32_t)(eptr->lastwrite+(eptr->timeout/3))<(uint32_t)now && eptr->outputhead==NULL) {
			matomlserv_createpacket(eptr,ANTOAN_NOP,0);
		}
		if (eptr->pdescpos>=0) {
			if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
				eptr->lastwrite = now;
				matomlserv_write(eptr);
			}
            if (eptr->mode!=KILL && eptr->logf && eptr->outputhead==NULL) {
                matomlserv_send_old_changes(eptr, eptr->currentversion);
            }
		}
		if ((uint32_t)(eptr->lastread+eptr->timeout)<(uint32_t)now) {
			eptr->mode = KILL;
		}
	}

// close
	kptr = &matomlservhead;
	while ((eptr=*kptr)) {
		if (eptr->mode == KILL) {
			matomlserv_beforeclose(eptr);
			tcpclose(eptr->sock);
			if (eptr->inputpacket.packet) {
				free(eptr->inputpacket.packet);
			}
			pptr = eptr->outputhead;
			while (pptr) {
				if (pptr->packet) {
					free(pptr->packet);
				}
				paptr = pptr;
				pptr = pptr->next;
				free(paptr);
			}
			if (eptr->servstrip) {
				free(eptr->servstrip);
			}
			*kptr = eptr->next;
			free(eptr);
		} else {
			kptr = &(eptr->next);
		}
	}
}
Exemplo n.º 23
0
void masterconn_read(masterconn *eptr) {
    int32_t i;
    uint32_t type,size;
    const uint8_t *ptr;
    for (;;) {
        i=read(eptr->sock,eptr->inputpacket.startptr,eptr->inputpacket.bytesleft);
        if (i==0) {
            syslog(LOG_NOTICE,"connection was reset by Master");
            eptr->mode = KILL;
            return;
        }
        if (i<0) {
            if (errno!=EAGAIN) {
                mfs_errlog_silent(LOG_NOTICE,"read from Master error");
                eptr->mode = KILL;
            }
            return;
        }
        stats_bytesin+=i;
        eptr->inputpacket.startptr+=i;
        eptr->inputpacket.bytesleft-=i;

        if (eptr->inputpacket.bytesleft>0) {
            return;
        }

        if (eptr->mode==HEADER) {
            ptr = eptr->hdrbuff+4;
            size = get32bit(&ptr);

            if (size>0) {
                if (size>MaxPacketSize) {
                    syslog(LOG_WARNING,"Master packet too long (%"PRIu32"/%u)",size,MaxPacketSize);
                    eptr->mode = KILL;
                    return;
                }
                eptr->inputpacket.packet = malloc(size);
                passert(eptr->inputpacket.packet);
                eptr->inputpacket.bytesleft = size;
                eptr->inputpacket.startptr = eptr->inputpacket.packet;
                eptr->mode = DATA;
                continue;
            }
            eptr->mode = DATA;
        }

        if (eptr->mode==DATA) {
            ptr = eptr->hdrbuff;
            type = get32bit(&ptr);
            size = get32bit(&ptr);

            eptr->mode=HEADER;
            eptr->inputpacket.bytesleft = 8;
            eptr->inputpacket.startptr = eptr->hdrbuff;

            masterconn_gotpacket(eptr,type,eptr->inputpacket.packet,size);

            if (eptr->inputpacket.packet) {
                free(eptr->inputpacket.packet);
            }
            eptr->inputpacket.packet=NULL;
        }
    }
}
Exemplo n.º 24
0
void masterconn_read(masterconn *eptr,double now) {
    int32_t i;
    uint32_t type,leng;
    const uint8_t *ptr;
    uint32_t rbleng,rbpos;
    uint8_t err,hup;
    static uint8_t *readbuff = NULL;
    static uint32_t readbuffsize = 0;

    if (eptr == NULL) {
        if (readbuff != NULL) {
            free(readbuff);
        }
        readbuff = NULL;
        readbuffsize = 0;
        return;
    }

    if (readbuffsize==0) {
        readbuffsize = 65536;
        readbuff = malloc(readbuffsize);
        passert(readbuff);
    }

    rbleng = 0;
    err = 0;
    hup = 0;
    for (;;) {
        i = read(eptr->sock,readbuff+rbleng,readbuffsize-rbleng);
        if (i==0) {
            hup = 1;
            break;
        } else if (i<0) {
            if (ERRNO_ERROR) {
                err = 1;
            }
            break;
        } else {
            stats_bytesin+=i;
            rbleng += i;
            if (rbleng==readbuffsize) {
                readbuffsize*=2;
                readbuff = mfsrealloc(readbuff,readbuffsize);
                passert(readbuff);
            } else {
                break;
            }
        }
    }

    if (rbleng>0) {
        eptr->lastread = now;
    }

    rbpos = 0;
    while (rbpos<rbleng) {
        if ((rbleng-rbpos)>=eptr->input_bytesleft) {
            memcpy(eptr->input_startptr,readbuff+rbpos,eptr->input_bytesleft);
            i = eptr->input_bytesleft;
        } else {
            memcpy(eptr->input_startptr,readbuff+rbpos,rbleng-rbpos);
            i = rbleng-rbpos;
        }
        rbpos += i;
        eptr->input_startptr+=i;
        eptr->input_bytesleft-=i;

        if (eptr->input_bytesleft>0) {
            break;
        }

        if (eptr->input_packet == NULL) {
            ptr = eptr->input_hdr;
            type = get32bit(&ptr);
            leng = get32bit(&ptr);

            if (leng>MaxPacketSize) {
                syslog(LOG_WARNING,"Master packet too long (%"PRIu32"/%u)",leng,MaxPacketSize);
                eptr->input_end = 1;
                return;
            }

            eptr->input_packet = malloc(offsetof(in_packetstruct,data)+leng);
            passert(eptr->input_packet);
            eptr->input_packet->next = NULL;
            eptr->input_packet->type = type;
            eptr->input_packet->leng = leng;

            eptr->input_startptr = eptr->input_packet->data;
            eptr->input_bytesleft = leng;
        }

        if (eptr->input_bytesleft>0) {
            continue;
        }

        if (eptr->input_packet != NULL) {
            *(eptr->inputtail) = eptr->input_packet;
            eptr->inputtail = &(eptr->input_packet->next);
            eptr->input_packet = NULL;
            eptr->input_bytesleft = 8;
            eptr->input_startptr = eptr->input_hdr;
        }
    }

    if (hup) {
        syslog(LOG_NOTICE,"connection was reset by Master");
        eptr->input_end = 1;
    } else if (err) {
        mfs_errlog_silent(LOG_NOTICE,"read from Master error");
        eptr->input_end = 1;
    }
}
Exemplo n.º 25
0
void masterconn_write(masterconn *eptr,double now) {
    out_packetstruct *opack;
    int32_t i;
#ifdef HAVE_WRITEV
    struct iovec iovtab[100];
    uint32_t iovdata;
    uint32_t leng;
    uint32_t left;

    for (;;) {
        leng = 0;
        for (iovdata=0,opack=eptr->outputhead ; iovdata<100 && opack!=NULL ; iovdata++,opack=opack->next) {
            iovtab[iovdata].iov_base = opack->startptr;
            iovtab[iovdata].iov_len = opack->bytesleft;
            leng += opack->bytesleft;
        }
        if (iovdata==0) {
            return;
        }
        i = writev(eptr->sock,iovtab,iovdata);
        if (i<0) {
            if (ERRNO_ERROR) {
                mfs_errlog_silent(LOG_NOTICE,"write to Master error");
                eptr->mode = KILL;
            }
            return;
        }
        if (i>0) {
            eptr->lastwrite = now;
        }
        stats_bytesout+=i;
        left = i;
        while (left>0 && eptr->outputhead!=NULL) {
            opack = eptr->outputhead;
            if (opack->bytesleft>left) {
                opack->startptr+=left;
                opack->bytesleft-=left;
                left = 0;
            } else {
                left -= opack->bytesleft;
                eptr->outputhead = opack->next;
                if (eptr->outputhead==NULL) {
                    eptr->outputtail = &(eptr->outputhead);
                }
                free(opack);
            }
        }
        if ((uint32_t)i < leng) {
            return;
        }
    }
#else
    for (;;) {
        opack = eptr->outputhead;
        if (opack==NULL) {
            return;
        }
        i=write(eptr->sock,opack->startptr,opack->bytesleft);
        if (i<0) {
            if (ERRNO_ERROR) {
                mfs_errlog_silent(LOG_NOTICE,"write to Master error");
                eptr->mode = KILL;
            }
            return;
        }
        if (i>0) {
            eptr->lastwrite = now;
        }
        stats_bytesout+=i;
        opack->startptr+=i;
        opack->bytesleft-=i;
        if (opack->bytesleft>0) {
            return;
        }
        eptr->outputhead = opack->next;
        if (eptr->outputhead==NULL) {
            eptr->outputtail = &(eptr->outputhead);
        }
        free(opack);
    }
#endif
}
Exemplo n.º 26
0
void csserv_read(csserventry *eptr) {
	int32_t i;
	uint32_t type,size;
	const uint8_t *ptr;

	if (eptr->mode == HEADER) {
		i=read(eptr->sock,eptr->inputpacket.startptr,eptr->inputpacket.bytesleft);
		if (i==0) {
//			syslog(LOG_NOTICE,"(read) connection closed");
			eptr->state = CLOSE;
			return;
		}
		if (i<0) {
			if (ERRNO_ERROR) {
				mfs_errlog_silent(LOG_NOTICE,"(read) read error");
				eptr->state = CLOSE;
			}
			return;
		}
		stats_bytesin+=i;
		eptr->inputpacket.startptr+=i;
		eptr->inputpacket.bytesleft-=i;

		if (eptr->inputpacket.bytesleft>0) {
			return;
		}

		ptr = eptr->hdrbuff+4;
		size = get32bit(&ptr);

		if (size>0) {
			if (size>MaxPacketSize) {
				syslog(LOG_WARNING,"(read) packet too long (%"PRIu32"/%u)",size,MaxPacketSize);
				eptr->state = CLOSE;
				return;
			}
			eptr->inputpacket.packet = malloc(size);
			passert(eptr->inputpacket.packet);
			eptr->inputpacket.startptr = eptr->inputpacket.packet;
		}
		eptr->inputpacket.bytesleft = size;
		eptr->mode = DATA;
	}
	if (eptr->mode == DATA) {
		if (eptr->inputpacket.bytesleft>0) {
			i=read(eptr->sock,eptr->inputpacket.startptr,eptr->inputpacket.bytesleft);
			if (i==0) {
//				syslog(LOG_NOTICE,"(read) connection closed");
				eptr->state = CLOSE;
				return;
			}
			if (i<0) {
				if (ERRNO_ERROR) {
					mfs_errlog_silent(LOG_NOTICE,"(read) read error");
					eptr->state = CLOSE;
				}
				return;
			}
			stats_bytesin+=i;
			eptr->inputpacket.startptr+=i;
			eptr->inputpacket.bytesleft-=i;

			if (eptr->inputpacket.bytesleft>0) {
				return;
			}
		}
		ptr = eptr->hdrbuff;
		type = get32bit(&ptr);
		size = get32bit(&ptr);

		eptr->mode = HEADER;
		eptr->inputpacket.bytesleft = 8;
		eptr->inputpacket.startptr = eptr->hdrbuff;

		csserv_gotpacket(eptr,type,eptr->inputpacket.packet,size);

		if (eptr->state != READ && eptr->state != WRITE) {
			if (eptr->inputpacket.packet) {
				free(eptr->inputpacket.packet);
			}
			eptr->inputpacket.packet=NULL;
		}
	}
}