欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

决定彻底放弃对MooseFS的研究

程序员文章站 2022-06-06 08:18:47
...

虽然对 分布式 也有一些了解,但是一直没有深入到代码去 研究 具体的实现。在群里咨询了一下,自己也google了一些资料,最终 决定 从MooseFS入手来深入 研究 分布式 系统 。第一步,就是从网上找文档,自己动手安装部署一番。官方网站上有一个中文的安装手册

虽然对分布式也有一些了解,但是一直没有深入到代码去研究具体的实现。在群里咨询了一下,自己也google了一些资料,最终决定从MooseFS入手来深入研究分布式系统。第一步,就是从网上找文档,自己动手安装部署一番。官方网站上有一个中文的安装手册,非常nice,整个安装配置过程也非常顺利,感觉还不错,就是看它的代码实现。看完之后有些失望,在main函数中的第一个函数strerr_init()中看到了这样的代码:

for (n=0 ; errtab[n].str ; n++) {}
而errtab的定义(部分)如下所示:

static errent errtab[] = {
#ifdef E2BIG
	{E2BIG,"E2BIG (Argument list too long)"},
#endif
#ifdef EACCES
	{EACCES,"EACCES (Permission denied)"},
#endif
......
	{0,NULL}
};
很明显,那个循环仅仅是为了计算errtab中元素的个数,而这样的计算有必要用一个循环么?sizeof不能解决么?我实现看不出来作者这里要写一个循环的好处是什么?

另一个地方让我感觉作者在写代码的时候很不用心,cfg_reload()在解析配置文件时定义了一个缓冲区linebuff[1000]数组来存储每行读取的内容。mfs解析配置文件时是按行读取的,每行的配置内容类似“key=value"这样的形式。这个缓冲区的长度定义为1000,也让我很不解。因为在定义缓冲区或分配内存的时候,一般都会考虑到对齐,都会对齐到word size或者CPU cache line的长度。这里的1000让我很不解!

代码中还有很多无用的、多余的判断。例如下面的代码段:

    logappname = cfg_getstr("SYSLOG_IDENT",STR(APPNAME));

	if (rundaemon) {
		if (logappname[0]) {
			openlog(logappname, LOG_PID | LOG_NDELAY , LOG_DAEMON);
		} else {
			openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);
		}
	} 
这个APPNAME是在编译的时候通过-DAPPNAME=mfsmaster这样的方式定义的一个宏,所以这个宏是必须定义的,否则前面的代码就没法运行(获取配置文件名称)。而且获取SYSLOG_IDENT配置变量的值是会指定默认值,所以if (logappname[0])这样的判断完全多余。如果是在两个函数中,这样的判断还说的过去,可是获取配置变量值的操作和
判断仅一个空行之隔,没必要到极点了吧。

抛开这些细节性的东西不提,mfs选择的I/O复用机制也让人不敢恭维。现在需要监听套接字的读写事件,毫无疑问首选的eventpoll。如果没有记错的话,moosefs是07年开始的,这个时候内核中的eventpoll机制已经很完善了,实在不懂作者为什么要选用poll()来作为I/O复用的接口。在继续之前,先看一下下面的代码:

        i = poll(pdesc,ndesc,50);
		......
		if (i  我不明白在poll()返回-1时,为什么要检查EAGAIN错误。查看了man手册,只有EFAULT、EINTR、EINVAL、ENOMEM错误,看了一下内核代码,也没有返回EAGAIN错误的地方。而且很不明白,为什么在EAGAIN的时候要调用usleep()等待100毫秒,不理解!

最终彻底击穿我的信心的是matoclserv_gotpacket()函数,这个函数通过判断eptr->registered的值来做不同的三种处理,这三个代码块中很多都是可以合并的。要么给每种处理封装成一个函数,要么将这三块代码合并成一块,这样看着不是更简洁么?很多switch-case分支中的处理也不用区分eptr->registered的值,为什么写的这么庞大?难道作者在写的时候为了方便,复制粘贴了一番?反正我是很不理解,这样的代码风格真是让我没办法看下去,我决定放弃了。我知道半途而废很不好,本来自己写代码风格就不好,怕看完之后更偏了,所以果断放弃

下面是matoclserv_gotpacket()函数的代码,大家欣赏一下:

void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *data,uint32_t length) {
	if (type==ANTOAN_NOP) {
		return;
	}
	if (eptr->registered==0) {	// unregistered clients - beware that in this context sesdata is NULL
		switch (type) {
			case CLTOMA_FUSE_REGISTER:
				matoclserv_fuse_register(eptr,data,length);
				break;
			case CLTOMA_CSERV_LIST:
				matoclserv_cserv_list(eptr,data,length);
				break;
			case CLTOMA_SESSION_LIST:
				matoclserv_session_list(eptr,data,length);
				break;
			case CLTOAN_CHART:
				matoclserv_chart(eptr,data,length);
				break;
			case CLTOAN_CHART_DATA:
				matoclserv_chart_data(eptr,data,length);
				break;
			case CLTOMA_INFO:
				matoclserv_info(eptr,data,length);
				break;
			case CLTOMA_FSTEST_INFO:
				matoclserv_fstest_info(eptr,data,length);
				break;
			case CLTOMA_CHUNKSTEST_INFO:
				matoclserv_chunkstest_info(eptr,data,length);
				break;
			case CLTOMA_CHUNKS_MATRIX:
				matoclserv_chunks_matrix(eptr,data,length);
				break;
			case CLTOMA_QUOTA_INFO:
				matoclserv_quota_info(eptr,data,length);
				break;
			case CLTOMA_EXPORTS_INFO:
				matoclserv_exports_info(eptr,data,length);
				break;
			case CLTOMA_MLOG_LIST:
				matoclserv_mlog_list(eptr,data,length);
				break;
			default:
				syslog(LOG_NOTICE,"main master server module: got unknown message from unregistered (type:%"PRIu32")",type);
				eptr->mode=KILL;
		}
	} else if (eptr->registeredsesdata==NULL) {
			syslog(LOG_ERR,"registered connection without sesdata !!!");
			eptr->mode=KILL;
			return;
		}
		switch (type) {
			case CLTOMA_FUSE_REGISTER:
				matoclserv_fuse_register(eptr,data,length);
				break;
			case CLTOMA_FUSE_RESERVED_INODES:
				matoclserv_fuse_reserved_inodes(eptr,data,length);
				break;
			case CLTOMA_FUSE_STATFS:
				matoclserv_fuse_statfs(eptr,data,length);
				break;
			case CLTOMA_FUSE_ACCESS:
				matoclserv_fuse_access(eptr,data,length);
				break;
			case CLTOMA_FUSE_LOOKUP:
				matoclserv_fuse_lookup(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETATTR:
				matoclserv_fuse_getattr(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETATTR:
				matoclserv_fuse_setattr(eptr,data,length);
				break;
			case CLTOMA_FUSE_READLINK:
				matoclserv_fuse_readlink(eptr,data,length);
				break;
			case CLTOMA_FUSE_SYMLINK:
				matoclserv_fuse_symlink(eptr,data,length);
				break;
			case CLTOMA_FUSE_MKNOD:
				matoclserv_fuse_mknod(eptr,data,length);
				break;
			case CLTOMA_FUSE_MKDIR:
				matoclserv_fuse_mkdir(eptr,data,length);
				break;
			case CLTOMA_FUSE_UNLINK:
				matoclserv_fuse_unlink(eptr,data,length);
				break;
			case CLTOMA_FUSE_RMDIR:
				matoclserv_fuse_rmdir(eptr,data,length);
				break;
			case CLTOMA_FUSE_RENAME:
				matoclserv_fuse_rename(eptr,data,length);
				break;
			case CLTOMA_FUSE_LINK:
				matoclserv_fuse_link(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETDIR:
				matoclserv_fuse_getdir(eptr,data,length);
				break;
/* CACHENOTIFY
			case CLTOMA_FUSE_DIR_REMOVED:
				matoclserv_fuse_dir_removed(eptr,data,length);
				break;
*/
			case CLTOMA_FUSE_OPEN:
				matoclserv_fuse_open(eptr,data,length);
				break;
			case CLTOMA_FUSE_READ_CHUNK:
				matoclserv_fuse_read_chunk(eptr,data,length);
				break;
			case CLTOMA_FUSE_WRITE_CHUNK:
				matoclserv_fuse_write_chunk(eptr,data,length);
				break;
			case CLTOMA_FUSE_WRITE_CHUNK_END:
				matoclserv_fuse_write_chunk_end(eptr,data,length);
				break;
// fuse - meta
			case CLTOMA_FUSE_GETTRASH:
				matoclserv_fuse_gettrash(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETDETACHEDATTR:
				matoclserv_fuse_getdetachedattr(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETTRASHPATH:
				matoclserv_fuse_gettrashpath(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETTRASHPATH:
				matoclserv_fuse_settrashpath(eptr,data,length);
				break;
			case CLTOMA_FUSE_UNDEL:
				matoclserv_fuse_undel(eptr,data,length);
				break;
			case CLTOMA_FUSE_PURGE:
				matoclserv_fuse_purge(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETRESERVED:
				matoclserv_fuse_getreserved(eptr,data,length);
				break;
			case CLTOMA_FUSE_CHECK:
				matoclserv_fuse_check(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETTRASHTIME:
				matoclserv_fuse_gettrashtime(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETTRASHTIME:
				matoclserv_fuse_settrashtime(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETGOAL:
				matoclserv_fuse_getgoal(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETGOAL:
				matoclserv_fuse_setgoal(eptr,data,length);
				break;
			case CLTOMA_FUSE_APPEND:
				matoclserv_fuse_append(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETDIRSTATS:
				matoclserv_fuse_getdirstats_old(eptr,data,length);
				break;
			case CLTOMA_FUSE_TRUNCATE:
				matoclserv_fuse_truncate(eptr,data,length);
				break;
			case CLTOMA_FUSE_REPAIR:
				matoclserv_fuse_repair(eptr,data,length);
				break;
			case CLTOMA_FUSE_SNAPSHOT:
				matoclserv_fuse_snapshot(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETEATTR:
				matoclserv_fuse_geteattr(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETEATTR:
				matoclserv_fuse_seteattr(eptr,data,length);
				break;
/* do not use in version before 1.7.x */
			case CLTOMA_FUSE_QUOTACONTROL:
				matoclserv_fuse_quotacontrol(eptr,data,length);
				break;
/* for tools - also should be available for registered clients */
			case CLTOMA_CSERV_LIST:
				matoclserv_cserv_list(eptr,data,length);
				break;
			case CLTOMA_SESSION_LIST:
				matoclserv_session_list(eptr,data,length);
				break;
			case CLTOAN_CHART:
				matoclserv_chart(eptr,data,length);
				break;
			case CLTOAN_CHART_DATA:
				matoclserv_chart_data(eptr,data,length);
				break;
			case CLTOMA_INFO:
				matoclserv_info(eptr,data,length);
				break;
			case CLTOMA_FSTEST_INFO:
				matoclserv_fstest_info(eptr,data,length);
				break;
			case CLTOMA_CHUNKSTEST_INFO:
				matoclserv_chunkstest_info(eptr,data,length);
				break;
			case CLTOMA_CHUNKS_MATRIX:
				matoclserv_chunks_matrix(eptr,data,length);
				break;
			case CLTOMA_QUOTA_INFO:
				matoclserv_quota_info(eptr,data,length);
				break;
			case CLTOMA_EXPORTS_INFO:
				matoclserv_exports_info(eptr,data,length);
				break;
			case CLTOMA_MLOG_LIST:
				matoclserv_mlog_list(eptr,data,length);
				break;
			default:
				syslog(LOG_NOTICE,"main master server module: got unknown message from mfsmount (type:%"PRIu32")",type);
				eptr->mode=KILL;
		}
	} else {	// old mfstools
		if (eptr->sesdata==NULL) {
			syslog(LOG_ERR,"registered connection (tools) without sesdata !!!");
			eptr->mode=KILL;
			return;
		}
		switch (type) {
// extra (external tools)
			case CLTOMA_FUSE_REGISTER:
				matoclserv_fuse_register(eptr,data,length);
				break;
			case CLTOMA_FUSE_READ_CHUNK:	// used in mfsfileinfo
				matoclserv_fuse_read_chunk(eptr,data,length);
				break;
			case CLTOMA_FUSE_CHECK:
				matoclserv_fuse_check(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETTRASHTIME:
				matoclserv_fuse_gettrashtime(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETTRASHTIME:
				matoclserv_fuse_settrashtime(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETGOAL:
				matoclserv_fuse_getgoal(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETGOAL:
				matoclserv_fuse_setgoal(eptr,data,length);
				break;
			case CLTOMA_FUSE_APPEND:
				matoclserv_fuse_append(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETDIRSTATS:
				matoclserv_fuse_getdirstats(eptr,data,length);
				break;
			case CLTOMA_FUSE_TRUNCATE:
				matoclserv_fuse_truncate(eptr,data,length);
				break;
			case CLTOMA_FUSE_REPAIR:
				matoclserv_fuse_repair(eptr,data,length);
				break;
			case CLTOMA_FUSE_SNAPSHOT:
				matoclserv_fuse_snapshot(eptr,data,length);
				break;
			case CLTOMA_FUSE_GETEATTR:
				matoclserv_fuse_geteattr(eptr,data,length);
				break;
			case CLTOMA_FUSE_SETEATTR:
				matoclserv_fuse_seteattr(eptr,data,length);
				break;
/* do not use in version before 1.7.x */
			case CLTOMA_FUSE_QUOTACONTROL:
				matoclserv_fuse_quotacontrol(eptr,data,length);
				break;
/* ------ */
			default:
				syslog(LOG_NOTICE,"main master server module: got unknown message from mfstools (type:%"PRIu32")",type);
				eptr->mode=KILL;
		}
	}
}