外篇  MOSIX集群係統

章節字數:5406  更新時間:08-10-24 23:53

背景顏色文字尺寸文字顏色鼠標雙擊滾屏 滾屏速度(1最快,10最慢)

    集群係統的各組成部分經常要互相通訊,MOSIX提供了一個連接層抽象(linkerlayer),在套接字接口之上使用TCP/UDP協議進行通信。

    作為一個集群係統,節點之間要經常合作,不時的散布和收集負載信息,獲取其它節點的情況。另外,我們也已經看到,在MOSIX中,一個遷移進程實際上是由deputy和remote兩部分組成的。Deputy和remote是兩個單獨的進程,分別位於不同的節點,但在邏輯上,它們卻是看出一個獨立的進程的。它們之間經常要通過頻繁的通訊來合作。因此,通信機製是至關重要的。MOSIX提供了一個連接層抽象(linkerlayer),在套接字接口之上封裝了一層,提供了一係列類似BSDSOCKET的接口函數用於在進程間接收和發送MOSIX相關數據的。MOSIX連接是位於內核中的,對用戶態進程是不可見的。

    作為一個集群係統,MOSIX中的每個節點都被分配一個唯一的節點號,節點號是一個整型值,從1開始連續分配的。0表示的是當前節點。通過節點號抽象,可以很方便的定位某個節點。但是通過網絡發送和接收數據,都是以IP地址來尋找節點的。因此,MOSIX係統提供了一係列函數用於在節點號和IP地址間的互相轉換和匹配。每個節點在/etc/目錄下都存在著一個配置文件mosix。map,保存著整個集群係統節點的IP地址信息。該文件的每一行都包含3個域,分別為節點範圍的起始號,IP地址或主機名,該範圍中的節點數目。例如某係統的配置文件如下:

    1172。26。4。1381

    2172。26。4。1392

    4MOSIX_41

    機器MOSIX_4的IP為172。26。4。22。在這個係統中,節點1的IP為172。26。4。138。節點2,3的IP則分別為172。26。4。139,172。26。4。140。節點4的IP則為172。26。4。22。

    數據結構

    structmosix_link表示一條MOSIX連接,它維持著該連接的狀態和一些控製信息。定義如下:

    structmosix_link{

    structsocket*sock;/*套接字控製結構,用於通訊,通過它進行實際的網絡操作*/

    intflags;/*狀態標誌*/

    intdlen;/*懸掛數據的長度*/

    intpeer;/*連接另一端的節點號*/

    char*hideptr;/*指向當前隱藏數據的指針*/

    char*hidebuf;/*指向隱藏數據緩衝區起始地址的指針*/

    inthidelen;/*隱藏數據的長度*/

    charhead[COMM_DEF_HEADSIZE];/*存放著消息頭*/

    };

    structcomm_header{消息格式

    unsignedshortolen;//Optiondatalength--

    unsignedshorthlen;

    inttype;

    intdlen;

    intregs;

    intdfsalen;

    };

    #defineCOMM_HLEN(sizeof(structcomm_header))

    MOSIX中,每個進程的控製塊中都保持著一條MOSIX連接contact(structmosix_link*contact),用於deputy和remote之間的通訊。進程的remote部分可以在節點間多次遷移,但是deputy總能根據它的contact連接來定位remote部分;remote也能根據它的contact連接和deputy部分通訊合作。對於未遷移的進程,contact總是為NULL。

    回頁首

    MOSIX連接層接口

    MOSIX連接層提供了一係列接口用於集群間進程之間互相發送和接收數據。從這些接口的名字上,我們就很容易判斷出它們的功能。

    comm_open():為MOSIX通訊打開一條連接

    mosix_link*comm_open(intmos,mosix_addr*maddr,unsignedlongtimo)

    如果mos0,則連接到第#mos號節點上的遷移守護進程。

    如果mos=COMM_TOADDR,則連接maddr-saddr中給定的地址。

    如果mos=COMM_ACCEPT,則打開一個SOCKET,並且可以接受連接。

    如果mos=COMM_MIGD,則為遷移守護進程設置SOCKET。

    如果mos=COMM_INFOD,則為信息守護進程設置SOCKET。

    如果mos=COMM_LOOSE,則允許連接多個守護進程。

    comm_use():為進程設置新的連接並返回舊的連接

    mosix_link*comm_use(structtask_struct*p,mosix_link*mlink)

    進程p將使用mlink連接進行通訊。

    comm_close():關閉Mosix通訊連接

    voidcomm_close(mosix_link*mlink)

    調用comm_shutdown(mlink)關閉對連接的寫入,然後通過sock_release(mlink-sock)釋放該連接上的套接字。

    comm_accept():在Mosix通訊套接字上接受連接

    intcomm_accept(mosix_link*ml,mosix_link**mlp,mosix_addr*ma,unsignedlongt)

    接受建立連接請求,mlp指向建立的新連接,連接的另一端的地址保存在ma中。

    comm_waitaccept():在Mosix通訊套接字上接受連接

    staticint

    comm_waitaccept()comm_waitaccept()調用comm_accept接收連接請求並建立一條新的連接,然後comm_use這條新的連接並關閉舊的連接。

    comm_send():發送一條消息(head+data)

    intcomm_send(inttype,void*head,inthlen,void*data,intdlen,intuspace)

    如果要發送的數據來自用戶空間(uspace),且可能會導致遠程page-fault(dirty_all_remote_pages),則先把數據從用戶空間拷入內核,然後檢查地址範圍的有效性(ucache_ok)。

    如果type&COMM_MFREGS或則type&COMM_MFIDENT,則分別通過comm_packregs(0,0)和comm_packident(0)進行壓縮,可能產生選項數據。

    將數據按照消息格式組裝起來,然後調用套接字操作集上的sendmsg操作將消息發送出去。

    comm_sendto():發送一個數據報

    intcomm_sendto(intmos,void*data,intlen,mosix_link*mlink,mosix_addr*to)

    通過mlink連接,發送len長的數據到to指明的地址,發送的數據在data中。

    to指明目的地址,如果為空,則數據是發送給節點mos上的負載信息守護進程(INFO_DAEMON)。

    調用套接字操作集上的sendmsg操作將消息發送到指定的地址。

    comm_dorecv():從連接中可靠的讀取數據

    intcomm_dorecv(structsocket*sock,structmsghdr*msg,intlen)

    根據msg,通過調用套接字操作集上的recvmsg操作從網絡連接上讀取數據。它讀的是字節流,並沒有格式的。

    comm_recv():接收消息頭

    intcomm_recv(void**headp,int*hlen)

    如果當前進程的連接處於等待接受連接請求狀態(COMM_WAITACCEPT),則等待直到接受請求。然後通過comm_dorecv()接收消息頭長度(COMM_HLEN)的數據,得到消息頭的實際長度(hlen+olen),然後準備空間存放消息頭數據(comm_mkhead),再通過comm_dorecv()接收實際的消息頭數據,並根據其中的信息,調用不同的解壓處理程序。因為為了減少傳輸的數據量,消息數據發送前都經過了壓縮。

    如果有數據COMM_MFDATA,則將數據長度保存在連接的數據長度中(mlink-dlen=header。dlen),這樣,隨後調用comm_copydata和comm_recvdata時,我們將知道應該能夠從網絡中讀取多少數據。

    comm_copydata():從消息中拷貝數據

    intcomm_copydata(void*data,intlen,intuspace)返回0表示成功。

    從消息中拷貝長度為len的數據。讀入的數據保存在data指向的buffer中。Uspace表明data是指向用戶空間還是內核空間。成功時返回0。

    如果要data指向用戶空間(uspace),且會導致遠程page-fault(dirty_all_remote_pages),則返回內存不足錯誤。

    如果連接中不存在數據,但是隱藏數據緩衝區不為空,則從隱藏數據緩衝區拷貝len長數據到data中。否則則通過comm_dorecv函數從網絡中讀取數據。

    comm_recvdata():從連接中將所有數據讀取到已分配緩衝區中/*

    intcomm_recvdata(void**data)返回0表示成功。

    如果連接中存在隱藏數據(COMM_HIDEDATA),則data指向隱藏數據緩衝區,然後置連接的隱藏數據緩衝區為NULL。

    否則,調用comm_malloc分配內存,通過comm_dorecv試圖將連接所有的數據(mlink-dlen)都接收放入到其中。data將指向分配的內存緩衝區。

    comm_recvfrom():接收數據報

    intcomm_recvfrom(void*data,intlen,mosix_link*mlink,mosix_addr*from,unsignedlongtimo)

    讀取長為len的數據放在data中,from返回接收數據報的源地址。timo指明超時值,單位為微秒。返回接收數據的長度(0)或者錯誤。

    調用套接字操作集上的recvmsg操作來接收數據,數據報的源地址返回在from中。如果接收到數據,則通過net_to_mos檢查該源地址是否屬於MOSIX節點。

    如果不屬於MOSIX節點,則comm_recvfrom()返回錯誤。

    comm_free():釋放不再被使用的消息頭或數據。

    voidcomm_free(void*head)

    如果當前進程的該連接是COMM_INFOLINK,則釋放head,返回。

    首先檢查head是否超出連接消息頭範圍。如果head指向消息頭的起始地址,則標記該消息頭不再被使用(~COMM_HEADINUSE)。否則釋放head所指的內存空間。

    comm_mkhead():準備指定大小的消息頭空間

    void*comm_mkhead(inthlen)

    從內核中分配hlen大小的GFP_KERNEL內存空間,mlink-head指向分配的起始地址。

    comm_flushdata():清空前一個消息剩餘的數據

    voidcomm_flushdata(intdlen)

    如果當前連接是隱藏數據(mlink-flags&COMM_HIDEDATA),則從隱藏數據中flush長度為dlen的數據。否則,調用comm_dorecv從連接中讀取長度為dlen的數據。

    comm_peek():檢查該連接是否有數據懸掛

    intcomm_peek(void)

    調用套接字操作集上的poll函數來判斷是否有數據懸掛。

    comm_poll():等待直到有通訊事件、中斷或MOSIX事件產生

    intcomm_poll(intmask,intinterruptible,unsignedlongtimo)

    interruptible指明是否可以被中斷,timeo設置等待超時時間。

    comm_wait():等待消息到達或者MOSIX事件產生

    intcomm_wait(void)

    返回1表示消息到達,返回0則表示先產生了一個事件。

    comm_send_urgent():使用緊急數據(OOB)發送事件通知

    intcomm_send_urgent(void)

    緊急事件通知隻能由代理發送。MOSIX中將OOB數據定為0xdb。它隻發送一個字節的有效數據(0xdb),通過將msghdr的msg_flags標誌位設置MSG_OOB|MSG_NOSIGNAL來表示緊急情況。

    comm_test_urgent():檢查是否懸掛了緊急數據(OOB)

    intcomm_test_urgent(void)

    通過設置MSG_OOB|MSG_PEEK|MSG_DONTWAIT|MSG_NOSIGNAL屬性來調用套接字操作集上的recvmsg操作來接收數據。如果接收到的長度為1且等於0xdb,則表明懸掛了緊急數據。

    comm_take_urgent():從流中取出懸掛的OOB數據,以免被轉化為普通數據處理

    voidcomm_take_urgent(void)

    調用者必須確保流中沒有其它的數據。

    首先以MSG_OOB|MSG_DONTWAIT|MSG_NOSIGNAL屬性讀取一字節,判斷是否有OOB數據,然後設置套接字SO_OOBINLINE選項為on,讓帶外數據保留在正常的輸入隊列中。然後調用套接字操作集上的recvmsg操作來讀取這一個字節的帶外數據。最後關閉套接字的SO_OOBINLINE選項。

    

    搜索關注 連城讀書 公眾號,微信也能看小說!或下載 連城讀書 APP,每天簽到領福利。

標題:
內容:
評論可能包含泄露劇情的內容
* 長篇書評設有50字的最低字數要求。少於50字的評論將顯示在小說的爽吧中。
* 長評的評分才計入本書的總點評分。

Copyright 2024 lcread.com All Rithts Reserved 版權所有,未經許可不得擅自轉載本站內容。
請所有作者發布作品時務必遵守國家互聯網信息管理辦法規定,我們拒絕任何反動、影射政治、黃色、暴力、破壞社會和諧的內容,讀者如果發現相關內容,請舉報,連城將立刻刪除!
本站所收錄作品、社區話題、書庫評論及本站所做之廣告均屬其個人行為,與本站立場無關。
如果因此產生任何法律糾紛或者問題,連城不承擔任何法律責任。