雖然對 分布式 也有一些了解,但是一直沒有深入到代碼去 研究 具體的實現。在群里咨詢了一下,自己也google了一些資料,最終 決定 從MooseFS入手來深入 研究 分布式 系統 。第一步,就是從網上找文檔,自己動手安裝部署一番。官方網站上有一個中文的安裝手冊
雖然對分布式也有一些了解,但是一直沒有深入到代碼去研究具體的實現。在群里咨詢了一下,自己也google了一些資料,最終決定從MooseFS入手來深入研究分布式系統。第一步,就是從網上找文檔,自己動手安裝部署一番。官方網站上有一個中文的安裝手冊,非常nice,整個安裝配置過程也非常順利,感覺還不錯,就是看它的代碼實現。看完之后有些失望,在main函數中的第一個函數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} };
另一個地方讓我感覺作者在寫代碼的時候很不用心,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); } }
拋開這些細節性的東西不提,mfs選擇的I/O復用機制也讓人不敢恭維。現在需要監聽套接字的讀寫事件,毫無疑問首選的eventpoll。如果沒有記錯的話,moosefs是07年開始的,這個時候內核中的eventpoll機制已經很完善了,實在不懂作者為什么要選用poll()來作為I/O復用的接口。在繼續之前,先看一下下面的代碼:
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()函數,這個函數通過判斷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->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; } } }
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com