雖然對(duì) 分布式 也有一些了解,但是一直沒有深入到代碼去 研究 具體的實(shí)現(xiàn)。在群里咨詢了一下,自己也google了一些資料,最終 決定 從MooseFS入手來深入 研究 分布式 系統(tǒng) 。第一步,就是從網(wǎng)上找文檔,自己動(dòng)手安裝部署一番。官方網(wǎng)站上有一個(gè)中文的安裝手冊(cè)
雖然對(duì)分布式也有一些了解,但是一直沒有深入到代碼去研究具體的實(shí)現(xiàn)。在群里咨詢了一下,自己也google了一些資料,最終決定從MooseFS入手來深入研究分布式系統(tǒng)。第一步,就是從網(wǎng)上找文檔,自己動(dòng)手安裝部署一番。官方網(wǎng)站上有一個(gè)中文的安裝手冊(cè),非常nice,整個(gè)安裝配置過程也非常順利,感覺還不錯(cuò),就是看它的代碼實(shí)現(xiàn)。看完之后有些失望,在main函數(shù)中的第一個(gè)函數(shù)strerr_init()中看到了這樣的代碼:
for (n=0 ; errtab[n].str ; n++) {}
static errent errtab[] = { #ifdef E2BIG {E2BIG,"E2BIG (Argument list too long)"}, #endif #ifdef EACCES {EACCES,"EACCES (Permission denied)"}, #endif ...... {0,NULL} };
另一個(gè)地方讓我感覺作者在寫代碼的時(shí)候很不用心,cfg_reload()在解析配置文件時(shí)定義了一個(gè)緩沖區(qū)linebuff[1000]數(shù)組來存儲(chǔ)每行讀取的內(nèi)容。mfs解析配置文件時(shí)是按行讀取的,每行的配置內(nèi)容類似“key=value"這樣的形式。這個(gè)緩沖區(qū)的長(zhǎng)度定義為1000,也讓我很不解。因?yàn)樵诙x緩沖區(qū)或分配內(nèi)存的時(shí)候,一般都會(huì)考慮到對(duì)齊,都會(huì)對(duì)齊到word size或者CPU cache line的長(zhǎng)度。這里的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); } }
拋開這些細(xì)節(jié)性的東西不提,mfs選擇的I/O復(fù)用機(jī)制也讓人不敢恭維。現(xiàn)在需要監(jiān)聽套接字的讀寫事件,毫無疑問首選的eventpoll。如果沒有記錯(cuò)的話,moosefs是07年開始的,這個(gè)時(shí)候內(nèi)核中的eventpoll機(jī)制已經(jīng)很完善了,實(shí)在不懂作者為什么要選用poll()來作為I/O復(fù)用的接口。在繼續(xù)之前,先看一下下面的代碼:
i = poll(pdesc,ndesc,50); ...... if (i<0) { if (errno==EAGAIN) { syslog(LOG_WARNING,"poll returned EAGAIN"); usleep(100000); continue; } if (errno!=EINTR) { syslog(LOG_WARNING,"poll error: %s",strerr(errno)); break; } } else { ...... }
最終徹底擊穿我的信心的是matoclserv_gotpacket()函數(shù),這個(gè)函數(shù)通過判斷eptr->registered的值來做不同的三種處理,這三個(gè)代碼塊中很多都是可以合并的。要么給每種處理封裝成一個(gè)函數(shù),要么將這三塊代碼合并成一塊,這樣看著不是更簡(jiǎn)潔么?很多switch-case分支中的處理也不用區(qū)分eptr->registered的值,為什么寫的這么龐大?難道作者在寫的時(shí)候?yàn)榱朔奖悖瑥?fù)制粘貼了一番?反正我是很不理解,這樣的代碼風(fēng)格真是讓我沒辦法看下去,我決定放棄了。我知道半途而廢很不好,本來自己寫代碼風(fēng)格就不好,怕看完之后更偏了,所以果斷放棄!
下面是matoclserv_gotpacket()函數(shù)的代碼,大家欣賞一下:
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->registered<100) { // mounts and new tools if (eptr->sesdata==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; } } }
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com