QNX之編寫資源管理器(十)

QNX相關(guān)歷史文章:

Filesystem Resource Managers

這篇文章主要描述文件系統(tǒng)資源管理器劲够。

1. Considerations for filesystem resource managers

由于文件系統(tǒng)資源管理器可能會(huì)收到很長(zhǎng)的路徑名,因此它必須要能夠正確地解析和處理路徑的每個(gè)部分蹲姐。
比如,一個(gè)資源管理器注冊(cè)了掛載點(diǎn)/mount柴墩,當(dāng)用戶輸入:ls -l /mount/home時(shí)江咳, 其中/mount/home是設(shè)備中的一個(gè)路徑,
那么ls會(huì)做以下事情:

d = opendir("/mount/home");
while (...) {
    dirent = readdir(d);
    ...
}

2. Taking over more than one device

當(dāng)資源管理器需要處理多個(gè)設(shè)備時(shí)歼指,可以對(duì)每個(gè)設(shè)備名調(diào)用resmgr_attach()接口進(jìn)行注冊(cè)踩身,此外每個(gè)設(shè)備還需要唯一的屬性結(jié)構(gòu),當(dāng)像chmod()等函數(shù)被調(diào)用時(shí)挟阻,便可對(duì)特定設(shè)備的屬性進(jìn)行修改。
示例代碼如下:

/* 
 *  MOD [1]:  allocate multiple attribute structures,
 *            and fill in a names array (convenience)
 */

#define NumDevices  2
iofunc_attr_t     sample_attrs [NumDevices];
char              *names [NumDevices] =
{
    "/dev/sample1",
    "/dev/sample2"
};

main ()
{
    ...
    /*
     *  MOD [2]:  fill in the attribute structure for each device 
     *           and call resmgr_attach for each device           
     */
    for (i = 0; i < NumDevices; i++) {
        iofunc_attr_init (&sample_attrs [i],
                          S_IFCHR | 0666, NULL, NULL);
        pathID = resmgr_attach (dpp, &resmgr_attr, name[i],
                                 _FTYPE_ANY, 0,
                                 &my_connect_funcs,
                                 &my_io_funcs,
                                 &sample_attrs [i]);
    }
    ...
}                            

在這個(gè)代碼中脱拼,增加了屬性結(jié)構(gòu)的數(shù)組熄浓,并且多次調(diào)用了resmgr_attach()接口击你,其他地方不需要修改。io_readio_write處理函數(shù)不需要改動(dòng)丁侄,iofunc layer默認(rèn)處理函數(shù)會(huì)去處理多種設(shè)備的情況鸿摇。

3. Handling directories

之前的例子路徑名都是在/dev目錄下,資源管理器不會(huì)限制只能在某個(gè)路徑下拙吉,并可以處理任何數(shù)量的路徑名,一個(gè)實(shí)際的限制在于當(dāng)數(shù)量越多的時(shí)候往史,可能面臨內(nèi)存不足以及查找速度慢等問題佛舱。
當(dāng)路徑名數(shù)量很多時(shí)挨决,一個(gè)最直接的辦法就是使用路徑名前綴订歪,比如:

  • CD-ROM文件系統(tǒng)刷晋,可以使用前綴/cdrom,當(dāng)對(duì)這個(gè)路徑下的名字操作時(shí)眼虱,都會(huì)去處理CD-ROM設(shè)備;
  • 一個(gè)處理壓縮文件的文件系統(tǒng)映凳,可以使用前綴/uncompressed邮破;
  • 網(wǎng)絡(luò)文件系統(tǒng)可以使用/mount/flipper路徑名來顯示遠(yuǎn)程機(jī)器仆救,當(dāng)訪問這個(gè)路徑時(shí)彤蔽,就像訪問本地機(jī)器;

上邊這些例子的特點(diǎn)是都實(shí)現(xiàn)了文件系統(tǒng)顿痪,文件系統(tǒng)資源管理器與設(shè)備資源管理器在以下幾個(gè)關(guān)鍵領(lǐng)域有區(qū)別:

  • resmgr_attach()參數(shù)中的_RESMGR_FLAG_DIR位會(huì)通知庫(kù)蚁袭,資源管理器會(huì)在掛載點(diǎn)路徑或掛載點(diǎn)路徑下接受匹配;
  • _IO_CONNECT邏輯必須根據(jù)數(shù)據(jù)權(quán)限和訪問權(quán)限來檢查路徑名的各個(gè)部分揩悄,它還必須確保在訪問特定文件名時(shí)綁定了適當(dāng)?shù)膶傩裕?/li>
  • _IO_READ邏輯必須返回路徑名指定的“文件”或“路徑”數(shù)據(jù)删性;

3.1 Matching at or below a mountpoint

在使用resmgr_attach()函數(shù)時(shí),傳入的flags參數(shù)為_RESMGR_FLAG_DIR時(shí)蹬挺,表明允許在指定的掛載點(diǎn)路徑或該路徑之下進(jìn)行路徑名解析巴帮。如果flags參數(shù)為0群发,表明使用默認(rèn)值发乔。

3.2 The _IO_OPEN message for filesystems

假設(shè)注冊(cè)了一個(gè)掛載點(diǎn)/sample_fsys,如下:

pathID = resmgr_attach
             (dpp,
             &resmgr_attr,
             "/sample_fsys",    /* mountpoint */
            _FTYPE_ANY,
             _RESMGR_FLAG_DIR,   /* it's a directory */
             &connect_funcs,
             &io_funcs,
             &attr);

當(dāng)客戶端調(diào)用如下代碼:

fopen ("/sample_fsys/spud", "r");

資源管理器會(huì)收到_IO_CONNECT消息起愈,并且調(diào)用io_read處理函數(shù)译仗。_IO_CONNECT消息的數(shù)據(jù)結(jié)構(gòu)如下:

struct _io_connect {
    unsigned short  type;
    unsigned short  subtype;     /* _IO_CONNECT_*              */
    unsigned long   file_type;   /* _FTYPE_* in sys/ftype.h    */
    unsigned short  reply_max;
    unsigned short  entry_max;
    unsigned long   key;
    unsigned long   handle;
    unsigned long   ioflag;      /* O_* in fcntl.h, _IO_FLAG_* */
    unsigned long   mode;        /* S_IF* in sys/stat.h        */
    unsigned short  sflag;       /* SH_* in share.h            */
    unsigned short  access;      /* S_I in sys/stat.h          */
    unsigned short  zero;
    unsigned short  path_len;
    unsigned char   eflag;       /* _IO_CONNECT_EFLAG_*        */
    unsigned char   extra_type;  /* _IO_EXTRA_*                */
    unsigned short  extra_len;
    unsigned char   path[1];     /* path_len, null, extra_len  */
};

其中ioflat, mode, sflag, access表明資源是如何打開的纵菌。參數(shù)path_len表明路徑名占多少字節(jié),path放置實(shí)際的路徑名笛辟。注意序苏,出現(xiàn)的路徑名是spud,而不是/sample_fsys/spud忱详,這是因?yàn)橄⒅话鄬?duì)于掛載點(diǎn)的路徑名匈睁。還要注意的是,路徑名中不會(huì)有相對(duì)路徑(., ..)部分航唆,也不會(huì)冗余的斜杠(/),這些都會(huì)在消息發(fā)送到資源管理器時(shí)被解析和刪除醇滥。

當(dāng)編寫文件系統(tǒng)資源管理器時(shí)超营,在處理路徑名時(shí)可能會(huì)有一些復(fù)雜的情況,為了驗(yàn)證訪問不跟,我們需要分解傳遞的路徑名米碰,并對(duì)每個(gè)部分進(jìn)行檢查购城∨耙耄可以使用strtok()等來分解路徑名字符串漆诽,然后調(diào)用iofunc_check_access()來進(jìn)行訪問驗(yàn)證。驗(yàn)證名稱之后發(fā)生的綁定要求處理的每個(gè)路徑都有自己的屬性結(jié)構(gòu)厢拭,如果將錯(cuò)誤的屬性綁定到所提供的路徑名供鸠,將會(huì)導(dǎo)致意外的行為。

3.3 Returning directory entries from _IO_READ

當(dāng)_IO_READ處理函數(shù)被調(diào)用后楞捂,可能需要返回文件(如果S_ISDIR(ocb->attr->mode)為false)泡一,也可能需要返回目錄(如果S_ISDIR(ocb->attr->mode)為true)觅廓。
對(duì)于將目錄返回給客戶端,存在一些約束杈绸,返回的不是一個(gè)字節(jié)流瞳脓,返回的是幾個(gè)struct dirent的數(shù)據(jù)結(jié)構(gòu),dirent結(jié)構(gòu)必須4字節(jié)對(duì)齊劫侧。數(shù)據(jù)結(jié)構(gòu)如下:

struct dirent {
#if _FILE_OFFSET_BITS - 0 == 64
    ino_t           d_ino;          /* File serial number. */
    off_t           d_offset;
#elif !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS == 32
#if defined(__LITTLEENDIAN__)
    ino_t           d_ino;          /* File serial number. */
    ino_t           d_ino_hi;
    off_t           d_offset;
    off_t           d_offset_hi;
#elif defined(__BIGENDIAN__)
    ino_t           d_ino_hi;
    ino_t           d_ino;          /* File serial number. */
    off_t           d_offset_hi;
    off_t           d_offset;
#else
 #error endian not configured for system
#endif
#else
 #error _FILE_OFFSET_BITS value is unsupported
#endif
    _Int16t             d_reclen;
    _Int16t             d_namelen;
    char                d_name[1];
};

d_ino成員包含一個(gè)掛載點(diǎn)唯一的文件序列號(hào)烧栋。這個(gè)序列號(hào)通常用于各種磁盤檢查程序中。在有些文件系統(tǒng)中珍特,d_offset用于標(biāo)識(shí)目錄條目本身魔吐,而在其他情況下莱找,它是下一個(gè)目錄項(xiàng)的偏移量嗜桌。d_reclen成員包含此目錄項(xiàng)的大小和任何其他相關(guān)信息骨宠。d_namelen參數(shù)指示d_name參數(shù)的大小,d_name保存該目錄項(xiàng)的實(shí)際名稱诱篷。
dirent結(jié)構(gòu)中僅包含名稱的前四個(gè)字節(jié)的空間棕所,_IO_READ處理程序需要返回一個(gè)更大的結(jié)構(gòu),包含名字和dirent琳省,如下:

struct {
    struct dirent ent;
    char namebuf[NAME_MAX + 1 + offsetof(struct dirent, d_name) -
                 sizeof( struct dirent)];
} entry

或者定義成聯(lián)合體:

union {
    struct dirent ent;
    char filler[ offsetof( struct dirent, dname ) + NAME_MAX + 1];
} entry;

在我們的io_read處理程序中针贬,需要生成許多struct dirent條目,并返回給客戶端桦他。如果在資源管理器中維護(hù)了目錄項(xiàng)緩存快压,那么構(gòu)造一組IOVs來指向這些項(xiàng)即可。如果沒有緩存的話蔫劣,則必須手動(dòng)將目錄項(xiàng)組裝到緩沖區(qū)中脉幢,然后返回指向該緩沖區(qū)的IOV。

3.3.1 Returning information associated with a directory structure

除了返回_IO_READ消息中的struct dirent外嫌松,還可以返回struct stat豆瘫,盡管這個(gè)可以提高效率,但是struct stat完全是可選的,如果不返回struct stat的話腻窒,客戶端就必須通過stat()/lstat()來獲取該信息磅崭。

客戶端可以通過將消息的xtype成員設(shè)置成_IO_XFLAG_DIR_EXTRA_HINT,以便向文件系統(tǒng)發(fā)送提示以返回額外的信息柔逼,但文件系統(tǒng)不保證這樣做割岛。如果資源管理器提供信息,則必須將其放入到struct dirent_extra_stat中维咸,定義如下:

struct dirent_extra_stat {
    _Uint16t            d_datalen;
    _Uint16t            d_type;
    _Uint32t            d_reserved;
    struct stat         d_stat;
};

資源管理器必須將d_type設(shè)置為_DTYPE_LSTAT_DTYPE_STAT惠爽,這取決于它是否解析符號(hào)鏈接。比如:

if(msg->i.xtype & _IO_XFLAG_DIR_EXTRA_HINT) { 
    struct dirent_extra_stat    extra;
    extra.d_datalen = sizeof extra.d_stat;
    extra.d_type = _DTYPE_LSTAT;
    extra.d_reserved = 0;
    iofunc_stat(ctp, &attr, &extra.d_stat);
    ...
}

每個(gè)目錄項(xiàng)后都有一個(gè)dirent_extra_stat

Returning the optional struct dirent_extra_stat along with the struct dirent entry can improve efficiency

dirent結(jié)構(gòu)必須在4字節(jié)邊界上對(duì)齊,dirent_extra_stat結(jié)構(gòu)必須在8字節(jié)邊界上對(duì)齊较性,d_reclen成員必須包含這兩個(gè)結(jié)構(gòu)的大小两残,包含路徑名和對(duì)齊所需的任何空間。最多不超過7字節(jié)的對(duì)齊填充人弓。

客戶端必須調(diào)用_DEXTRA_*()宏來檢查額外的數(shù)據(jù)着逐,如果檢查失敗耸别,則需要顯示調(diào)用lstat()stat()。比如秀姐,ls -l檢查額外的_DTYPE_LSTAT信息,如果不存在痒留,ls調(diào)用lstat()ls -L檢查額外的_DTYPE_STAT信息匾效,如果不存在恤磷,ls調(diào)用stat()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末魔策,一起剝皮案震驚了整個(gè)濱河市河胎,隨后出現(xiàn)的幾起案子仿粹,更是在濱河造成了極大的恐慌,老刑警劉巖吭历,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晌区,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恼五,警方通過查閱死者的電腦和手機(jī)哭懈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睬罗,“玉大人旭斥,你說我怎么就攤上這事』ㄑ危” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵柒昏,是天一觀的道長(zhǎng)也祠。 經(jīng)常有香客問我,道長(zhǎng)堪旧,這世上最難降的妖魔是什么奖亚? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任昔字,我火速辦了婚禮,結(jié)果婚禮上陨囊,老公的妹妹穿的比我還像新娘夹攒。我一直安慰自己,他們只是感情好咏尝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布编检。 她就那樣靜靜地躺著,像睡著了一般厕怜。 火紅的嫁衣襯著肌膚如雪累驮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音置侍,去河邊找鬼。 笑死蜡坊,一個(gè)胖子當(dāng)著我的面吹牛秕衙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播据忘,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼勇吊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了礼殊?” 一聲冷哼從身側(cè)響起针史,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婚陪,沒想到半個(gè)月后射亏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡及舍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年锯玛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兼蜈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歼郭,死狀恐怖辐棒,靈堂內(nèi)的尸體忽然破棺而出牍蜂,到底是詐尸還是另有隱情泰涂,我是刑警寧澤逼蒙,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站僵井,受9級(jí)特大地震影響妖泄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹈胡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一罚渐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧合砂,春花似錦源织、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至互亮,卻和暖如春余素,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桨吊。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工屏积, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姥卢。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓渣聚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親棺榔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隘道,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • QNX相關(guān)歷史文章:QNX簡(jiǎn)介QNX Neutrino微內(nèi)核QNX IPC機(jī)制QNX進(jìn)程管理器QNX資源管理器QN...
    Loyen閱讀 2,202評(píng)論 0 0
  • QNX相關(guān)歷史文章:QNX簡(jiǎn)介QNX Neutrino微內(nèi)核QNX IPC機(jī)制QNX進(jìn)程管理器QNX資源管理器QN...
    Loyen閱讀 6,604評(píng)論 0 12
  • QNX相關(guān)歷史文章:QNX簡(jiǎn)介QNX Neutrino微內(nèi)核QNX IPC機(jī)制QNX進(jìn)程管理器QNX資源管理器QN...
    Loyen閱讀 3,313評(píng)論 0 0
  • QNX相關(guān)歷史文章:QNX簡(jiǎn)介QNX Neutrino微內(nèi)核QNX IPC機(jī)制QNX進(jìn)程管理器 1. Introd...
    Loyen閱讀 4,403評(píng)論 1 4
  • QNX相關(guān)歷史文章:QNX簡(jiǎn)介QNX Neutrino微內(nèi)核QNX IPC機(jī)制QNX進(jìn)程管理器QNX資源管理器QN...
    Loyen閱讀 6,508評(píng)論 0 1